DEV Community

Cover image for Guestbook application using Fission & CockroachDB
Atulpriya Sharma
Atulpriya Sharma

Posted on • Originally published at deploy-preview-169--fission-website.netlify.app

Guestbook application using Fission & CockroachDB

Fission provides you with a serverless framework that you can deploy on your Kubernetes clusters.There are various use cases where you can use Fission, and today we'll show you how to develop a guestbook application with Fission in Go using CockroachDB as a database.

Serverless Guestbook Application

The guestbook is composed with four REST APIs and each API consist of a function and an HTTP trigger. This application allows a user to create, edit and delete a message. You can submit a message, retrieve a list of messages, delete a message all by means of REST APIs.
You can clone Fission REST API Repo and follow the guide to install/try guestbook sample.

Create Fission Objects for REST API

A REST API uses HTTP method to determine what's the action server needs to perform on resource(s) represents in the URL.

POST   http://api.example.com/user-management/users/{id}
PUT    http://api.example.com/user-management/users/{id}
GET    http://api.example.com/user-management/users/{id}
DELETE http://api.example.com/user-management/users/{id}
Enter fullscreen mode Exit fullscreen mode

To create a REST API with fission, we need to create following things to make it work:

  • HTTP Trigger with specific HTTP method and URL contains the resource type we want to manipulate with. Read more about HTTP Triggers
  • Function to handle the HTTP request. Read more about Function

Installation

HTTP Trigger

The first step is to create an HTTP trigger for your function

$ fission httptrigger create --url /guestbook/messages --method POST --function restapi-post --name restpost
Enter fullscreen mode Exit fullscreen mode

There are 3 important elements in the command:

  • method: The HTTP method of REST API
  • url: The API URL contains the resource placeholder
  • function: The function reference to a fission function

As a real world REST API, the URL would be more complex and contains the resource placeholder.
To support such use cases, you can change URL to something like following:

$ fission httptrigger create --url "/guestbook/messages/{id:[0-9]+}" --method GET --function restapi-get --name restgetpart
Enter fullscreen mode Exit fullscreen mode

Since fission uses gorilla/mux as underlying URL router, you can write regular expression in URL to filter out illegal API requests.

$ fission httptrigger create --url "/guestbook/messages/{id:[0-9]+}" --method GET --function restapi-get --name restgetpart
Enter fullscreen mode Exit fullscreen mode

Function

To handle a REST API request, normally a function need to extract resource from the request URL. In Fission, you can get the resource value from request header directly as we described in Request Payload.

That means you can get value from header with key X-Fission-Params-Id if URL is /guestbook/messages/{id}.

In Go, you can use CanonicalMIMEHeaderKey to transform letter case.

import (
    "net/textproto"
)

const (
    URL_PARAMS_PREFIX = "X-Fission-Params"
)

func GetPathValue(r *http.Request, param string) string {
    // transform text case
    // For example: 'id' -> 'Id', 'fooBAR' -> 'Foobar', 'foo-BAR' -> 'Foo-Bar'.
    param = textproto.CanonicalMIMEHeaderKey(param)

    // generate header key for accessing request header value
    key := fmt.Sprintf("%s-%s", URL_PARAMS_PREFIX, param)

    // get header value
    return r.Header.Get(key)
}
Enter fullscreen mode Exit fullscreen mode

When Golang server receive HTTP requests, it dispatches entrypoint function and passes whole response writer and request object to the function.

func MessageGetHandler(w http.ResponseWriter, r *http.Request) {
    ...
}
Enter fullscreen mode Exit fullscreen mode

In this way, you can access query string and message body as usual.

func GetQueryString(r *http.Request, query string) string {
    return r.URL.Query().Get(query)
}
Enter fullscreen mode Exit fullscreen mode
body, err := ioutil.ReadAll(r.Body)
if err != nil {
    err = errors.Wrap(err, "Error reading request body")
    log.Println(err.Error())
    w.WriteHeader(http.StatusBadRequest)
    w.Write([]byte(err.Error()))
    return
}
Enter fullscreen mode Exit fullscreen mode

CockroachDB Setup

In guestbook application we need to store messages in a database.
Since fission is build on top of kubernetes, it's very easy to achieve this by creating Kubernetes Service(svc) and Deployment.
For this sample application, we are using CockroachDB.

We also have a post on using PostgreSQL with Fission that you might want to read too.

Access 3rd service

Add cockroachdb helm repo

helm repo add cockroachdb https://charts.cockroachdb.com/
helm repo update
Enter fullscreen mode Exit fullscreen mode

Install cockroachdb using helm and provide values from cockroachdb.yaml

helm install my-release --values cockroachdb.yaml cockroachdb/cockroachdb
Enter fullscreen mode Exit fullscreen mode

Guestbook Application Setup

Create the go environment

fission env create --name go --image fission/go-env-1.16 --builder fission/go-builder-1.16
Enter fullscreen mode Exit fullscreen mode

Create a sourcepackage from the rest-api folder.
It is required to create a package.

zip -j restapi-go-pkg.zip rest-api/*
Enter fullscreen mode Exit fullscreen mode

Create a package from the source archive

fission pkg create --name restapi-go-pkg --sourcearchive restapi-go-pkg.zip --env go
Enter fullscreen mode Exit fullscreen mode

Create functions for GET, POST, DELETE, UPDATE

fission fn create --name restapi-delete --executortype newdeploy --maxscale 3 --env go --pkg restapi-go-pkg --entrypoint MessageDeleteHandler
fission fn create --name restapi-update --executortype newdeploy --maxscale 3 --env go --pkg restapi-go-pkg --entrypoint MessageUpdateHandler
fission fn create --name restapi-post --executortype newdeploy --maxscale 3 --env go --pkg restapi-go-pkg --entrypoint MessagePostHandler
fission fn create --name restapi-get --executortype newdeploy --maxscale 3 --env go --pkg restapi-go-pkg --entrypoint MessageGetHandler
Enter fullscreen mode Exit fullscreen mode

Create HTTPTriggers for the endpoints for the above created functions

fission httptrigger create --url /guestbook/messages --method POST --function restapi-post --name restpost
fission httptrigger create --url "/guestbook/messages/{id:[0-9]+}" --method PUT --function restapi-update --name restupdate
fission httptrigger create --url "/guestbook/messages/{id:[0-9]+}" --method GET --function restapi-get --name restgetpart
fission httptrigger create --url "/guestbook/messages/{id:[0-9]+}" --method DELETE --function restapi-delete --name restdelete
fission httptrigger create --url "/guestbook/messages/" --method GET --function restapi-get --name restget
Enter fullscreen mode Exit fullscreen mode

Fission Spec

The entire installation can be done using a single block of fission spec commands as shown below

fission spec init
fission env create --name go --image fission/go-env-1.16 --builder fission/go-builder-1.16 --spec
fission pkg create --name restapi-go-pkg --sourcearchive restapi-go-pkg.zip --env go --spec
fission fn create --name restapi-delete --executortype newdeploy --maxscale 3 --env go --pkg restapi-go-pkg --entrypoint MessageDeleteHandler --spec
fission fn create --name restapi-update --executortype newdeploy --maxscale 3 --env go --pkg restapi-go-pkg --entrypoint MessageUpdateHandler --spec
fission fn create --name restapi-post --executortype newdeploy --maxscale 3 --env go --pkg restapi-go-pkg --entrypoint MessagePostHandler --spec
fission fn create --name restapi-get --executortype newdeploy --maxscale 3 --env go --pkg restapi-go-pkg --entrypoint MessageGetHandler --spec
fission httptrigger create --url /guestbook/messages --method POST --function restapi-post --spec --name restpost
fission httptrigger create --url "/guestbook/messages/{id:[0-9]+}" --method PUT --function restapi-update --spec --name restupdate
fission httptrigger create --url "/guestbook/messages/{id:[0-9]+}" --method GET --function restapi-get --spec --name restgetpart
fission httptrigger create --url "/guestbook/messages/{id:[0-9]+}" --method DELETE --function restapi-delete --spec --name restdelete
fission httptrigger create --url "/guestbook/messages/" --method GET --function restapi-get --spec --name restget
Enter fullscreen mode Exit fullscreen mode

It will create a specs folder with all the required yaml files post which you can apply the changes

fission spec apply
Enter fullscreen mode Exit fullscreen mode

Testing The Guestbook Application

Since this guestbook application is created using REST APIs, we first need to export the $FISSION_ROUTER along with the port

export PORT=8889
kubectl --namespace fission port-forward $(kubectl --namespace fission get pod -l svc=router -o name) $PORT:8888
export FISSION_ROUTER=127.0.0.1:$PORT
Enter fullscreen mode Exit fullscreen mode

Create a post

curl -v -X POST \
    http://${FISSION_ROUTER}/guestbook/messages \
    -H 'Content-Type: application/json' \
    -d '{"message": "hello world!"}'
Enter fullscreen mode Exit fullscreen mode

Get all posts

curl -v -X GET http://${FISSION_ROUTER}/guestbook/messages/
Enter fullscreen mode Exit fullscreen mode

It will return a list of all the messages


[
    {
        "id": 366739357484417025,
        "message": "hello world!",
        "timestamp": 1531990369
    },
    {
        "id": 366739413774237697,
        "message": "hello world!",
        "timestamp": 1531990387
    },
    {
        "id": 366739416644550657,
        "message": "hello world!",
        "timestamp": 1531990399
    }
]
Enter fullscreen mode Exit fullscreen mode

You can also get a single post using the id

curl -v -X GET http://${FISSION_ROUTER}/guestbook/messages/366456868654284801
Enter fullscreen mode Exit fullscreen mode

Updating a post

curl -v -X PUT \
    http://${FISSION_ROUTER}/guestbook/messages/366456868654284801 \
    -H 'Content-Type: application/json' \
    -d '{"message": "hello world again!"}'
Enter fullscreen mode Exit fullscreen mode

Deleting a post

curl -X DELETE \
    http://${FISSION_ROUTER}/guestbook/messages/366456868654284801 \
    -H 'Cache-Control: no-cache'
Enter fullscreen mode Exit fullscreen mode

Conclusion

At this point you know how to create a simple guestbook application using REST APIs and database on Fission.This was a simple application to show you the capabilities of Fission.You can try to create your own application which may be more complex than this one.

This article was originally posted on Fission.io

Top comments (0)