Search code examples
oracle-cloud-infrastructurefn

GET method not allowed to fn applications


I'm new to the Fn project, have created the first app in java using fn init --runtime java HelloWorld-func and tried few other scenarios, but faced an issue with GET call.

  1. Not able to make GET call, but POST call works fine. I didn't make any changes to the source code, using the default one which created using the fn init command.

curl -X GET http://localhost:8080/invoke/01EJTD2K1JNG8G00GZJ0000002 {"message":"Method not allowed: GET /invoke/01EJTD2K1JNG8G00GZJ0000002"}

  1. What is the use of triggers?

fn version 0.5.97

thanks.


Solution

  • In Fn there are two built-in ways of invoking functions

    • The invoke API (e.g. POST http://localhost:8080/invoke/01EJTD2K1JNG8G00GZJ0000002 )
    • HTTP Triggers (e.g. GET/PUT/POST/HEAD http://localhost:8080/t/appname/triggername)

    These serve different purposes:

    The invoke API is system to system API designed to allow software and systems to invoke functions as part of their code - to give an example you might use this if you were writing an application where you wanted to use functions to handle internal application events. This API has a narrow contract to make it easier for client applications to handle errors and tell the difference between when a function raised an error or the fn server raised an error. This API only accepts POST requests, and only returns a limited set of response codes.

    HTTP Triggers on the other hand are a built-in way to expose functions directly on their own HTTP endpoints (e.g. for serving a web page, or handling an API that you define).

    Triggers take a raw HTTP request from a client (which can have any verb like PUT/POST/HEAD and any HTTP headers) and wrap the request in a call to the underlying function which can then extract information about the request and generate an HTTP respond. In Oracle Cloud Infrastructure you can do the same thing but you would use an API Gateway rather than a trigger to receive the incoming request (see below).

    Internally you can see triggers as a layer on top of the invoke endpoint that wraps an HTTP request into an invocation on the invoke API, calls the function with the wrapped request and then unwraps HTTP response information from the function back into an HTTP request.

    So the key difference between the invoke API and a trigger or API gateway is that on the invoke API Fn defines the API (to make it easier to build software on top of Fn) but on a trigger you define the API - you can capture the full request and define the full HTTP response.

    In Fn if you wanted to expose a REST API implemented by a function that handled a GET and returned a web page you would:

       fn create trigger <appname> <funcname> <triggername>  --type http  --source http 
    
    • Get the published trigger endpoint:
    fn list trigger <appname> 
    
    testapp testtrigger 01E6YM3R80NG8G00GZJ000000R  http    /trig   http://localhost:8080/t/node/trig
    
    • Invoke the function via its HTTP endpoint
    curl http://localhost:8080/t/node/trig
    ...
    

    In Oracle Cloud Infrastructure you can do the same thing by creating an API Gateway that binds the function to an HTTP endpoint. An example of how do do this is documented here:

    https://blogs.oracle.com/developers/creating-your-first-api-gateway-in-the-oracle-cloud https://blogs.oracle.com/developers/working-with-http-in-oracle-functions-using-the-fn-project-python-fdk