Here is my Log book
Invoking the function directly
Building on from the previous days. What might not have been obvious at first is that you can invoke the function by talking directly to the API end point and not needing to use faas-cli invoke
$ curl --data-binary '{"key":"value"}' --header "Content-Type: application/json" http://192.168.64.4:8080/function/helloworld
{"key":"value"}
Warm up for tonight – JSON prettifier
I am going to see if I can modify the helloworld function to take JSON as input and prettify it.
But first I will test out the code in the Python REPL
$ python
>>> import json
>>> req = '{"z": 1, "a": 2, "c": 3, "b": 4}'
>>> data = json.loads(req)
>>> response = json.dumps(data, indent=4, sort_keys=True)
>>> response
'{\n "a": 2, \n "b": 4, \n "c": 3, \n "z": 1\n}'
Ok that worked so next I need to modify the [handler.py](http://handler.py)
file. Disclaimer: I am not worried about error handling or any of the production coding here.
import json
def handle(req):
data = json.loads(req)
response = json.dumps(data, indent=4, sort_keys=True)
return response
Rebuild and redeploy with faas-cli
$ faas-cli up -f helloworld.yml
...
Deployed. 200 OK.
URL: http://192.168.64.4:8080/function/helloworld.openfaas-fn
Verify by throwing some JSON at it
$ curl --data-binary '{"z": 1, "a": 2, "c": 3, "b": 4}' --header "Content-Type: application/json" http://192.168.64.4:8080/function/helloworld
{
"a": 2,
"b": 4,
"c": 3,
"z": 1
}
Nice one! I also checked Docker Hub and indeed there is only 1 image that has been updated.
Lets write a function that calls a 3rd party API
For this I am going to be following the example from Serverless for Everyone Else that uses Node.js.
Which API to call? In the book Alex uses http://open-notify.org to get the number of Astronauts currently in space. I will be using their API that gives the geolocation of where the International Space Station is.
See "International Space Station Current Location" for more information on the API as well as a Python example.
International Space Station Location
Create a new function from the node12 template
╭ ~/Learning/faasd [20:23:45]
╰ $ faas-cli new --lang node12 iss-location
Whoops! I forgot to first create a directory in which to create the files, so now the files are mixed with my other function.
$ mkdir temp
$ mv iss* temp
$ mv template temp
$ mv temp iss-location
$ ls
helloworld/ iss-location/ password.txt
$ cd iss-location
Time to write some code $ mate iss-location/handler.js
(I love TextMate, been my text editor on mac for probably 10 years). Note: I am not proficient in JS or node.
'use strict'
const axios = require("axios")
module.exports = async (event, context) => {
let issResponse = await axios.get("http://api.open-notify.org/iss-now.json")
let body = {"lat": issResponse.data.iss_position.latitude,
"long": issResponse.data.iss_position.longitude
}
return context
.status(200)
.headers({"Content-type": "application/json"})
.succeed(body)
}
Need to install axios package first.
$ npm install --save axios
Build and deploy the function.
$ faas-cli up -f iss-location.yml
...
Deployed. 200 OK.
URL: http://192.168.64.4:8080/function/iss-location.openfaas-fn
I tried to curl the end point and nothing. I checked the UI and it says "not ready". Ok so something is wrong (and I bet my code is wrong).
$ faas-cli describe iss-location
Name: iss-location
Status: Not Ready
Replicas: 0
Available replicas: 0
Invocations: 1
Image:
Function process: node index.js
It says that the status = Not Ready and also the Replicas = 0 (whereas my other functions = 1)
$ curl -i http://192.168.64.4:8080/function/iss-location
HTTP/1.1 500 Internal Server Error
Content-Length: 0
Content-Type: text/plain
Date: Thu, 11 Mar 2021 20:58:45 GMT
X-Call-Id: 50fb978e-160f-4f5e-824e-f5bcd4db5100
X-Duration-Seconds: 0.000556
X-Start-Time: 1615496325470597568
Learning action point: I do wonder how can you get to error logs or something when things go wrong on the webserver / multipass instance? At the moment the debugging is, poke something and see if it works.
Ok I have narrowed it down to node not being happy about the line: const axios = require("axios") which means it can’t find the node package. Watching Alex’s workshop video I can see that I was suppose to install axios inside the directory where the handler.js file is.
╭ ~/Learning/faasd/iss-location/iss-location [21:09:59]
╰ $ ls
handler.js node_modules/ package-lock.json package.json
$ faas-cli describe iss-location
Name: iss-location
Status: Ready
Replicas: 1
Bingo! Ok time to put all the code back like I wrote it earlier in this post and then faas-cli up
again.
Moment of truth
$ faas-cli up -f iss-location.yml
...
$ curl http://192.168.64.4:8080/function/iss-location
{"lat":"-50.3286","long":"-138.4613"}
Woo hoo!