A First Look at FnProject
Yesterday at the Java One Keynote Mark Cavage and Chad Arimura announced the release of FnProject which is an Open-Source, container-based, cloud-agnostic FaaS platform.
FnProject
FnProject is language agnostic - a function is a container image and what goes in it is up to you. The contract is over STDIN/OUT, so if your favourite language can use those then you can use fn
. Even if your favourite language is Befunge.
Getting started, installing Fn
Everything starts with the fn
command, so we’d better install it:
$ curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
fn version 0.4.6
And create our first function
$ fn init --runtime=go
______
/ ____/___
/ /_ / __ \
/ __/ / / / /
/_/ /_/ /_/
Runtime: go
Function boilerplate generated.
func.yaml created.
We’ve used runtime=go
because runtime=befunge
isn’t supported yet (PRs accepted look here), so we have 3 files created by the go
template.
func.go
is a super-simple go program which:- (optionally) reads JSON from STDIN
- Prints some JSON to STDOUT
func.yaml
is the metadata for this function. For now we’ll accept the defaultstest.json
specifies some expected input/output values.
From this point on, you will need a newish version of Docker, which is FnProject’s only dependency.
So what can we do?
Run the function
$ fn run
Building image my-first-function:0.0.1
Sending build context to Docker daemon 5.12kB
Step 1/8 : FROM funcy/go:dev as build-stage
---> 4cccab7fc828
Step 2/8 : WORKDIR /function
---> Using cache
---> 3cbac4137ce0
Step 3/8 : ADD . /go/src/func/
---> cd9dfe6d13f9
Removing intermediate container 8c80673c236f
Step 4/8 : RUN cd /go/src/func/ && go build -o func
---> Running in 78ca7f971b61
---> bea65786d05d
Removing intermediate container 78ca7f971b61
Step 5/8 : FROM funcy/go
---> 573e8a7edc05
Step 6/8 : WORKDIR /function
---> Using cache
---> 5e1dd9693dd5
Step 7/8 : COPY --from=build-stage /go/src/func/func /function/
---> Using cache
---> 532f355bbd08
Step 8/8 : ENTRYPOINT ./func
---> Using cache
---> 14d0cde76c0f
Successfully built 14d0cde76c0f
Successfully tagged my-first-function:0.0.1
{"message":"Hello World"}
There’s a bit of docker output there, but the last 2 lines are important: We’ve built a totally standard container image (try it with docker run
if you don’t believe me), and the last line is our function’s output.
Check that STDIN parsing is working:
$ echo '{"name": "Matthew"}' | fn run
...
{"message":"Hello Matthew"}
Test the function
Check that the spec provided in test.json
is adhered to:
$ fn test
...
Running 2 tests...running tests on my-first-function:0.0.1 :
Test 1
PASSED - ( 925.574963ms )
Test 2
PASSED - ( 1.123083022s )
2 tests passed, 0 tests failed.
Running as a service
Now we’ve seen an easy way to create functions, how about deploying them? FnProject can run anywhere a container can. The easiest place to start with is right where you already are, so start the fn service already:
$ fn start
...
time="2017-10-03T08:18:54Z" level=info msg="available memory" ram=266539061248
time="2017-10-03T08:18:54Z" level=info msg="Serving Functions API on address `:8080`"
______
/ ____/___
/ /_ / __ \
/ __/ / / / /
/_/ /_/ /_/
v0.3.135
That’ll sit there in the foreground, so in another terminal we can deploy our app to the localhost server:
$ fn deploy --app my-app --local
...
Successfully tagged my-first-function:0.0.4
Updating route /my-first-function using image my-first-function:0.0.4...
In the command above, --app my-app
is necessary as functions must be namespaced into apps. I’m using --local
to skip the step where fn
will try to push my image to a repository (default: Dockerhub).
Now we can call our function as a web service
$ curl -d '{"name": "Matthew over HTTP"}' http://localhost:8080/r/my-app/my-first-function
{"message": "Hello Matthew over HTTP"}
Fin
That was a super-quick look at how to get started with FnProject - I hope it was helpful. There’s a lot more documentation if you need it, and there’s a lot more to fn, too.
Next post I’ll look at the Java support. If you have any questions - there’s an official Fn Slack channel, problems - there’s GitHub issues or just ask on Slack.