Expose OCI Functions with different HTTP Methods on API Gateway

Expose OCI Functions with different HTTP Methods on API Gateway

This article is an extension of this one, explaining the OCI Functions context and data.

Let’s say that you have an OCI function that is used to get, insert, and delete customers from a database.

You want to expose the function through an API Gateway to implement authentication and/or authorization for example, or maybe you want to limit the number of requests to the back-end, etc.

You could create three different functions for each action and you would expose each one under a separate endpoint on API Gateway like:

  • /myproject/v1/get-all-customers
  • /myproject/v1/create-customer
  • /myproject/v1/delete-customer

but, this is bad practice.

You should create all three actions under the same endpoint:

  • /myproject/v1/customers
    • use GET to get all customers
    • use POST to insert new customers
    • use DELETE to delete customers

Let’s see how we can do that with OCI Functions and OCI API Gateway.

Function Configuration

Create the function

When writing the function, you would want to know whether the invocation was a GET, POST, or DELETE. We can get that information from the function context object.

Let’s start by generating a new hello-world sample in python:

fn init --runtime python oci-fn-http-method

Note: If you need help generating new functions, you can check this article about setting up the environment for OCI Functions.

Now let’s modify the func.py so it does different things depending on the HTTP verb:

import io
import json
import logging

from fdk import response


def handler(ctx, data: io.BytesIO=None):
    resp = {}  
    
    if ctx.Method() == "GET":
        # do smth when the function is invoked using the GET verb
        resp = get_method()
      
    if ctx.Method() == "POST":
        # do smth when the function is invoked using the PSOT verb
        resp = post_method()
        
    if ctx.Method() == "DELETE":
        # do smth when the function is invoked using the DELETE verb
        resp = delete_method()
    
    return response.Response(
        ctx, response_data=json.dumps(resp),
        headers={"Content-Type": "application/json"}
    )


def get_method():
    return {"method": "GET", "message" : "The function was called using a GET verb"}


def post_method():
    return {"method": "POST", "message" : "The function was called using a POST verb"}


def delete_method():
    return {"method": "DELETE", "message" : "The function was called using a DELETE verb"}

Note: If you want to know more about the context object, check this article out.

When calling the function, the ctx object passed to the handler contains a lot of information about the function, the environment, the caller, and the invocation. We can take out the HTTP verb from ctx.Method() and do different actions depending on the HTTP method.

Deploy the function

Before deploying the function to OCI, we must first create an application that will hold the function.

We can do that by going in the main menu, under Developer Services – Functions click on Create Application:

From inside the function folder, deploy to the application created from the OCI Console – mine was create-bucket-app

fn -v deploy --app create-bucket-app

Note: If you need help deploying the function, check this OCI Functions Quickstart.

API Gateway Configuration

Create the endpoint

Once the function is deployed to OCI, we can expose it through an API Gateway.

Create a new API Gateway, from the main menu – Developer Services – API Gateway.

In the API Gateway, create a new deployment, and first, give your deployment a name, a path prefix and select the compartment where you want to deploy it: Then, create a new route:

  • Give a path (this is the path to the resource, you can have multiple routes for a single deployment, like /fn/resource1, /fn/resource2, etc.)
  • The HTTP method(s)
  • The back-end type: at the moment it can be HTTP, Oracle Functions and Stock Response – I’ll select Oracle Functions
  • Select the application where you deployed your function – mine was create-bucket-app
  • Select the function you want to call – mine was oci-fn-http-method

Click Next and Create.

Wait a couple of seconds until the deployment changes state to Active and then, copy the endpoint:

Test the endpoint

Let’s give it a try and call the endpoint using GET, POST and DELETE as HTTP methods to see that it works. I’m going to use Postman for this, but you can use any other tool you want to make the calls.

After copying the deployment endpoint, don’t forget to add the resource path – in my case, it was: …/fn (endpoint path) /hello (resource path)

  • GET

  • POST – a little side note, you need to send an empty raw body for this to work via Postman

  • DELETE

Conclusions

OCI Functions offers an easy solution for this kind of use cases – get the HTTP method from the Function’s context object. Like this, we can deploy a function on a single resource path in API Gateway for multiple HTTP methods.

This is a good way to avoid creating multiple resource paths in API Gateway for the same kind of resource. Now, it is safe to say that the function should not do too many things, it is supposed to be a single-purpose piece of code, so try to keep it as simple as possible.

Ionut Adrian Vladu

I enjoy building python scripts for…everything! I am a Cloud enthusiast and I like to keep up with technology. When I'm not behind a computer, I like taking photos -- Visit My 500px profile -- or sit back and enjoy Formula 1 race weekends. Currently, working as a Tech Cloud Specialist @ Oracle
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments