How to Develop a Serverless Application with Fission (Part 3)
Categories:
Introduction
At Part 2, we knew what’s real payload was passed to function and how to create a serverless guesbook. In the last post, we will go through the final bank sample and know how to deploy a application to different fission clusters.
A Serverless Bank Application in Golang (Sample)
In this section, we use a more complex bank sample to demonstrate how to use AJAX interacts with fission functions.
Installation
You can clone repo below and follow the guide to install/try bank sample.
AJAX and CORS
AJAX (Asynchronous JavaScript and XML) allows JavaScript sending requests to remote server without refreshing web page which quite suitable for using fission function to handle the requests.
Following is the sample code using jQuery to send AJAX requests to backend fission function on path “/accounts”.
$.ajax({
origin: "*",
type: 'POST',
url: '/accounts', // RESTful API function path
crossDomain: true,
data: JSON.stringify(data),
contentType: "application/json",
error: function (xhr) {
$('#alert-danger').html('('+xhr.status+') '+xhr.responseText).show();
return false;
},
success: function (response) {
$('#alert-success').html(response).show();
window.location.href = "./login.html";
return true;
}
});
In this sample, we put both website pages and fission functions under same domain. For most cases, however, the web pages are often served with different domain and hitting CORS(Cross-Origin Resource Sharing) problem like following.
To fix this, we have to add couple change to our function.
- Add CORS header to response header
- Add OPTIONS pre-flight request handler
Add CORS header to response header
Browser checks whether response contains CORS headers. So before replying user request call setCORS()
to add header.
For more details about CORS header, please visit https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS.
func reply(msg []byte, code int, w http.ResponseWriter) {
w = setCORS(w) // set CORS header
w.WriteHeader(code)
w.Write(msg)
}
func setCORS(w http.ResponseWriter) http.ResponseWriter {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "*")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Methods", "*")
w.Header().Set("Access-Control-Expose-Headers", "*")
return w
}
Add OPTIONS pre-flight request handler
From the graph above, we can see that browser will send OPTIONS request to remote server. So we should add another function to handle such requests.
func CorsOptionsHandler(w http.ResponseWriter, r *http.Request) {
setCORS(w).WriteHeader(http.StatusOK)
}
And you need to create OPTIONS http triggers point to options-handler
function for every URL endpoint.
$ fission route list|grep OPTIONS
e019d4be-fdfe-404a-bfca-5a5b24fe531f OPTIONS /accounts false options-handler
6fac456d-d155-422c-8580-c464ba308050 OPTIONS /accounts/ false options-handler
4452f18c-f9b2-40d6-b676-ee868627e237 OPTIONS /sessions false options-handler
3f74a3a1-edc5-470d-bbcd-4395377705a1 OPTIONS /transaction false options-handler
93845c23-eadb-4335-9a1c-1ddec0da19bd OPTIONS /transaction/withdraw false options-handler
ba9c8cdb-ad31-4eec-9ae9-00001fdd85e6 OPTIONS /transaction/deposit false options-handler
6b2be34d-5f07-4426-8baf-951c71db3602 OPTIONS /transaction/transfer false options-handler
Deploy the Same Application to Different Environment
In the last section of the post, assume you already created a serverless application on your own cluster. You may start wondering is there any way to migrate a application from one cluster to another?
The answer is YES.
Consider most of developers have different environments (e.g. Canary, Production) to test and run with.
Fission allows users to deploy the same application with spec
files. A spec file is a Fission Object in YAML format includes all necessary information.
Here is a sample YAML that describe a go environment:
apiVersion: fission.io/v1
kind: Environment
metadata:
creationTimestamp: null
name: go
namespace: default
spec:
TerminationGracePeriod: 360
builder:
command: build
image: fission/go-builder
keeparchive: false
poolsize: 3
resources: {}
runtime:
functionendpointport: 0
image: fission/go-env
loadendpointpath: ""
loadendpointport: 0
version: 2
The best thing is you don’t need to write YAML files by hand. You can create with CLI directly.
Here are steps for how to create application spec files:
- Create spec directory
- Create fission resources with flag
--sepc
- Check spec files under
spec
directory
$ fission spec init
$ fission env create --name go --image fission/go-env --builder fission/go-builder --spec
$ cat specs/env-go.yaml
After creating all fission objects for application, you can deploy & destroy an application with apply
command:
$ fission spec apply
Now, the go environment was created automatically.
$ fission env list
NAME UID IMAGE POOLSIZE MINCPU MAXCPU MINMEMORY MAXMEMORY EXTNET GRACETIME
go d30a78ee-a618-11e8-a55e-08002720b796 fission/go-env 3 0 0 0 0 false 360
But what about archiving source code into source package? Is there any way to archive it automatically?
At Part 1 we use ZIP
command to
archive source package. You can achieve this by writing a ArchiveUploadSpec
YAML file like following. fission spec
will automatically archives files list on include
field once it detects ArchiveUploadSpec
exists.
apiVersion: fission.io/v1
kind: Package
metadata:
name: bank-go-pkg
namespace: default
spec:
source:
url: archive://bank-go-zip # need to match source archive name below
buildcmd: "build"
environment:
name: go
namespace: default
status:
buildstatus: pending
---
kind: ArchiveUploadSpec
name: bank-go-zip # source archive name
include:
- "functions/*.go"
- "functions/vendor"
After apply
command, you shall see a package was created.
$ fission pkg list
NAME BUILD_STATUS ENV
bank-go-pkg succeeded go
NOTE: Currently, v0.10.0 doesn’t support to create spec files for archiving package. There is an issue trying to address the problem and will be released in 0.11.0.
Conclusion
After all 3 parts of this post, hope you understand fission more well and start using fission as FaaS solution on kubernetes. Since fission is a growing project, feel free to join the Fission community to share your idea with us! :)
Authors:
- Ta-Ching Chen | Fission Contributor | Tech blog