Serverless GoLang Code Sharing Between Functions

Original Post

Hello,

I’m in the process of learning Serverless, particularly using the GoLang implementation and I understand the basics to enough of an extent that I have started building a Serverless web service.

However, I’m having problems adhering to DRY principles. For example, assume that a basic authentication exists whereby a function is called with a username and password and assuming the corresponding user exists a JWT token is returned with the payload in the token being a JSON representation of the following struct for that user.

// user.go (pseudo code)
type User struct {
    Username string `json:"username"`
    ...
}

When a request to an authenticated function is made, I want to have a authorisation check that will validate the JWT token of the request, Unmarshal the token payload to the above struct so it is available for use in the function handler. The check would resemble something like this:

// authentication.go (pseudo code)

// GetJWTSession is responsible for taking an APIGatewayProxyRequest
// with a valid JWT Token Authorization Header and returning a User struct
// instance for the corresponding user relative to the jwt payload
func GetJWTSession(request events.APIGatewayProxyRequest) (user.User, error) {
    session := user.User{}

    payload, err := jwt.decode(request.Headers.Authorization)

    if err != nil {
        return nil, err
    }

    err = json.Unmarshal([]byte(payload), &session)

    if err != nil {
        return nil, err
    }

    return session, nil
}

The above example would require two shared files to exist user.go which exports the struct used here session := user.User{} and authentication.go the file that the above function would be defined in.

This would mean in the authenticated functions, something along the following lines could be used:

// GetSecretRecipes Function (pseudo code)
package main

import ( ... )

type Request events.APIGatewayProxyRequest;
type Response request events.APIGatewayProxyResponse;

func handle(context context.Context, request Request) (response Response, error) {
     session, err := authentication.GetJWTSession(request)
    
     if err != nil {
         return Response{ StatusCode: http.StatusUnauthorized }, err
     }

     // ... authenticated successfully
}

func main() {
    lambda.Start(handle)
}

How would I approach having a shared code base that functions in my service can use?

I feel like I’m missing something really straightforward? :thinking:

Thanks for any help!

I feel like I’m missing something really straightforward? :thinking:

This was the case. This post can be removed to prevent confusion.