Fn Framework
Fn was announced in 2017 by Oracle at the JavaOne 2017 conference as an event-driven and open source Function-as-a-Service (FaaS) platform. The key characteristics of the framework are as follows:
- Open source: All the source code of the Fn project is publicly available at https://github.com/fnproject/fn, and the project is hosted at https://fnproject.io. It has an active community on GitHub, with more than 3,300 commits and 1,100 releases, as shown in the following screenshot:
Figure 3.1: Fn at GitHub
- Container-native: Containers and microservices have changed the manner of software development and operations. Fn is container-native, meaning that each function is packaged and deployed as a Docker container. Also, it is possible to create your own Docker container and run them as functions.
- Language support: The framework officially supports Go, Java, Node.js, Ruby, and Python. In addition, C# is supported by the community.
- Cloud-agnostic: Fn can run on every cloud provider or on-premise system, as long as Docker is installed and running. This is the most critical characteristic of Fn, since it avoids the vendor lock-in problem completely. If the functions do not depend on any cloud-specific service, it is possible to move between cloud providers and on-premise systems quickly.
As a cloud-agnostic and container-native platform, Fn is a developer-focused framework. It enhances developer experience and agility since you can develop, test, and debug locally and deploy to cloud with the same tooling. In the following exercise, we will install and configure Fn so that we can start using the framework.
Note
Docker 17.10.0-ce or later should be installed and running on your computer before you start the next exercise, since this is a prerequisite for Fn.
Exercise 7: Getting Started with the Fn Framework
In this exercise, you will install and configure a cloud-agnostic and container-native serverless framework on your local computer. The aim of this exercise is to illustrate how straightforward it is to configure and install the Fn Framework so that you can get started with serverless frameworks.
To complete this exercise successfully, we need to ensure that the following steps are executed:
- In your Terminal, type the following command:
curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
This command downloads and installs the Fn framework. Once this is complete, the version number is printed out, as shown in the following screenshot:
Figure 3.2: Installation of Fn
- Start the Fn server by using the following command in your Terminal:
fn start -d
This command downloads the Docker image of the Fn server and starts it inside a container, as shown in the following screenshot:
Figure 3.3: Starting the Fn server
- Check the client and server version by using the following command in your Terminal:
fn version
The output should be as follows:
Figure 3.4: Fn server and client version
This output shows that both the client and server side are running and interacting with each other.
- Update the current Fn context and set a local development registry:
fn use context default && fn update context registry serverless
The output is shown in the following screenshot:
Figure 3.5: Registry setup for the current context
As the output indicates, the default context is set, and the registry is updated to serverless.
- Start the Fn dashboard by using the following command in your Terminal:
docker run -d --link fnserver:api -p 4000:4000 -e "FN_API_URL=http://api:8080" fnproject/ui
This command downloads the fnproject/ui image and starts it in detached mode. In addition, it links fnserver:api to itself and publishes the 4000 port, as shown in the following screenshot:
Figure 3.6: Starting the Fn UI
- Check the running Docker containers with the following command:
docker ps
As expected, two containers are running for Fn with the image names fnproject/ui and fnproject/fnserver:latest, respectively, as shown in the following screenshot:
Figure 3.7: Docker containers
- Open http://localhost:4000 in your browser to check the Fn UI.
The Fn Dashboard lists the applications and function statistics as a web application, as shown in the following screenshot:
Figure 3.8: Fn Dashboard
With this exercise, we have installed the Fn framework, along with its client, server, and dashboard. Since Fn is a cloud-agnostic framework, it is possible to install any cloud or on-premise system with the illustrated steps. We will continue discussing the Fn framework in terms of how the functions are configured and deployed.
The Fn framework is designed to work with applications, where each application is a group of functions with their own route mappings. For instance, let's assume you have grouped your functions into a folder, as follows:
- app.yaml
- func.yaml
- func.go
- go.mod
- products/
- func.yaml
- func.js
- suppliers/
- func.yaml
- func.rb
In each folder, there is a func.yaml file that defines the function with the corresponding implementation in Ruby, Node.js, or any other supported language. In addition, there is an app.yaml file in the root folder to define the application.
Let's start by checking the content of app.yaml:
name: serverless-app
app.yaml is used to define the root of the serverless application and includes the name of the application. There are also three additional files for the function in the root folder:
- func.go: Go implementation code
- go.mod: Go dependency definitions
- func.yaml: Function definition and trigger information
For a function with an HTTP trigger and Go runtime, the following func.yaml file is defined:
name: serverless-app
version: 0.0.1
runtime: go
entrypoint: ./func
triggers:
- name: serverless-app
type: http
source: /serverless-app
When you deploy all of these functions to Fn, they will be accessible via the following URLs:
http://serverless-kubernetes.io/ -> root function
http://serverless-kubernetes.io/products -> function in products/ directory
http://serverless-kubernetes.io/suppliers -> function in suppliers/ directory
In the following exercise, the content of the app.yaml and func.yaml files, as well as their function implementation, will be illustrated with a real-life example.
Exercise 8: Running Functions in the Fn Framework
In this exercise, we aim to create, deploy, and invoke a function using the Fn framework.
To complete this exercise successfully, we need to ensure that the following steps are executed:
- In your Terminal, run the following commands to create an application:
mkdir serverless-app
cd serverless-app
echo "name: serverless-app" > app.yaml
cat app.yaml
The output should be as follows:
Figure 3.9: Creating the application
These commands create a folder called serverless-app and then change the directory so that it's in this folder. Finally, a file called app.yaml is created with the content name: serverless-app, which is used to define the root of the application.
- Run the following command in your Terminal to create a root function that's available at the "/" of the application URL:
fn init --runtime ruby --trigger http
This command will create a Ruby function with an HTTP trigger at the root of the application, as shown in the following screenshot:
Figure 3.10: Ruby function creation
- Create a subfunction by using the following commands in your Terminal:
fn init --runtime go --trigger http hello-world
This command initializes a Go function with an HTTP trigger in the hello-world folder of the application, as shown in the following screenshot:
Figure 3.11: Go function creation
- Check the directory of the application by using the following command in your Terminal:
ls -l .
This command lists the files in the root and child folders, as shown in the following screenshot:
Figure 3.12: Folder structure
As expected, there is a Ruby function in the root folder with three files: func.rb for the implementation, func.yaml for the function definition, and Gemfile to define Ruby function dependencies.
Similarly, there is a Go function in the hello-world folder with three files: func.go for the implementation, func.yaml for the function definition, and go.mod for Go dependencies.
- Deploy the entire application by using the following command in your Terminal:
fn deploy --create-app --all --local
This command deploys all the functions by creating the app and using a local development environment, as shown in the following screenshot:
Figure 3.13: Application deployment to Fn
Firstly, the function for serverless-app is built, and then the function and trigger are created. Similarly, the hello-world function is built and deployed with the corresponding function and trigger.
- List the triggers of the application with the following command and copy the Endpoints for serverless-app-trigger and hello-world-trigger:
fn list triggers serverless-app
This command lists the triggers of serverless-app, along with function, type, source, and endpoint information, as shown in the following screenshot:
Figure 3.14: Trigger list
- Trigger the endpoints by using the following commands in your Terminal:
Note
For the curl commands, do not forget to use the endpoints that we copied in Step 5.
curl -d Ece http://localhost:8080/t/serverless-app/serverless-app
The output should be as follows:
Figure 3.15: Invocation of the serverless-app trigger
This command will invoke the serverless-app trigger located at the root of the application. Since it was triggered with the name payload, it responded with a personal message: Hello Ece!:
curl http://localhost:8080/t/serverless-app/hello-world
This command will invoke the hello-world trigger without any payload and, as expected, it responded with Hello World, as shown in the following screenshot:
Figure 3.16: Invocation of the hello-world trigger
- Check the application and function statistics from the Fn Dashboard by opening http://localhost:4000 in your browser.
On the home screen, your applications and their overall statistics can be seen, along with auto-refreshed charts, as shown in the following screenshot:
Figure 3.17: Fn Dashboard – Home
Click on serverless-app from the applications list to view more information about the functions of the application, as shown in the following screenshot:
Figure 3.18: Fn Dashboard – Application
- Stop the Fn server by using the following command in your Terminal:
fn stop
This command will stop the Fn server, including all the function instances, as shown in the following screenshot:
Figure 3.19: Fn server stop
In this exercise, we created a two-function application in the Fn framework and deployed it. We have shown you how to build functions as Docker containers using the fn client and by creating functions. In addition, the triggers of the functions were invoked via HTTP, and the statistics were checked from the Fn dashboard. As a container-native and cloud-agnostic framework, the functions of the framework are Docker containers, and they can run on any cloud provider or local system. In the next section, another serverless framework, namely, the Serverless Framework, which focuses more on cloud-provider integration, will be presented.