Being on the job hunt for my first web developer role I realized that knowledge and experience with serverless architecture are required and critical for most positions.
During my Full-Stack Web Development training program, I already built an authorization server with the Serverless Toolkit and AWS Lambda. But, only practice makes perfect, and I wanted to have another project to cement what I've learned.
As I'm currently re-reading the Harry Potter book series, I had the idea to build a Sorting Service that assigns a user to a random Hogwarts house. Besides, it should show other students already living in this house. To fetch data about characters, I used this Harry Potter API.
With Node
, Serverless Toolkit
, AWS Lambda
, and API Gateway
we'll build a simple API that returns a random Hogwarts house as well as some housemates.
Prerequisites
Before we can start with the actual project, we need to have Node
and npm
installed, as well as create and activate our own AWS account.
Installing the Serverless Toolkit and Creating a Serverless Service
One reason we'll use the Serverless Toolkit
here is, that we'll have to install axios
, later on, to fetch data from the Potter API and Serverless
lets us easily do this. I also like Serverless
when working with AWS
because it's easier to implement code or deploy functions locally without having to work with the inline code editor in AWS
.
To install Serverless
globally and create a Node
template, we run the following commands:
npm install -g serverless
serverless create --template aws-nodejs --path random-sorting-service
cd random-sorting-service
npm init // creates a package.json
Our directory structure should look like this now:
📦random-sorting-service
┣ 📜.gitignore
┣ 📜handler.js // here we'll write our sorting function
┣ 📜package.json
┗ 📜serverless.yml // here we'll configure our function
Configuring AWS Credentials
To make sure the Serverless Toolkit
can interact with AWS
we need to configure and add our AWS
credentials. We'll create an access key that allows us to configure the Serverless Toolkit
and enable it to deploy functions directly to AWS
.
To achieve this, we have to follow these steps:
- Log in to our newly created
AWS
account by clicking on "Sign in to the Console". - Click on our username in the upper right-hand corner and select "My Security Credentials".
- Select "Access keys" and click the "Create New Access Key" button.
- Download the new access key (it contains an access key ID and a secret access key) and store it in a safe place.
Back in our terminal, we run the following command (using our own credentials):
serverless config credentials --provider aws --key ACCESS_KEY_ID --secret SECRET_ACCESS_KEY
Configuring and Setting Up serverless.yml
We now open the serverless.yml
file in our code editor and declare our sections as follows:
Writing the Lambda Function
The Random House Generator
We open the handler.js
file, delete the dummy code, and replace it with the following:
Let's take a closer look at the code example above:
The function is named getRandomHouseAndHousemates
because in Step 2 we'll also fetch data of associated house members.
First, we put all four Hogwarts houses inside an array. Then, we create a random index
that is used to display a random house. We use the Math.random()
function that returns a floating-point, pseudo-random number between 0 (inclusive) and 1 (exclusive). We also need the Math.floor()
function to get a whole number and not a floating type. Because Math.floor()
returns a number representing the largest integer less than or equal to the specified number, if passing Math.random()
as a parameter to Math.floor()
, we get a whole number.
But there is one problem left we have to handle: Math.floor()
is always rounding down to the nearest decimal, so every decimal between 0 and less than 1 (and that is what Math.random()
is returning) will always be 0. To get a random number between 0 and 4 (the length of our houses
array) we have to multiply the Math.random()
by randomHouse.length
. This index
now can be applied to get a random house.
Because we'll have cross-origin requests if we'd want to use our service within another app, we also have to add the Access-Control-Allow-Origin
header to the return statement in handler.js
Testing the Random House Generator
Before deploying, we can test our function locally. For now, it should only return a random Hogwarts house. From inside our project directory, we run:
serverless invoke local --function getRandomHouseAndHousemates
If everything works as expected, we should see something like this in our terminal:
{
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*"
},
"body": "{\"randomHouse\":\"Hufflepuff\"}"
}
If that works, we can go on and implement the additional logic to fetch and return data about our new housemates.
Getting data from 3rd party API
In order to be able to make requests to the Harry Potter API, inside our random-sorting-service
folder, we run:
npm install axios
In our handler.js
, we add the code we need to get and return our housemates' data:
Let's take a closer look at this code example, too:
In our handler.js
, we have to require axios
. Then, we use the randomHouse
variable declared in the first step to generate the URL to reach the API endpoint we need. Subsequently, we make the API request. As getRandomHouseAndHousemates
already is an async
function, we'll use a try...catch
block to handle possible request errors with axios
.
Because we plan to return only students from the same house, but the given endpoint returns teachers as well as students, we have to apply the filter()
method to the API response as well.
Testing the API Request
Now it is time to test our function locally again before we finally can deploy:
serverless invoke local --function getRandomHouseAndHousemates
We should see something similar to that in our terminal:
{
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*"
},
"body": "{\"randomHouse\":\"Ravenclaw\",\"housemates\":[{\"name\":\"Cho Chang\",\"species\":\"human\",\"gender\":\"female\",\"house\":\"Ravenclaw\",\"dateOfBirth\":\"\",\"yearOfBirth\":\"\",\"ancestry\":\"\",\"eyeColour\":\"brown\",\"hairColour\":\"black\",\"wand\":{\"wood\":\"\",\"core\":\"\",\"length\":\"\"},\"patronus\":\"swan\",\"hogwartsStudent\":true,\"hogwartsStaff\":false,\"actor\":\"Katie Leung\",\"alive\":true,\"image\":\"http://hp-api.herokuapp.com/images/cho.jpg\"},{\"name\":\"Luna Lovegood\",\"species\":\"human\",\"gender\":\"female\",\"house\":\"Ravenclaw\",\"dateOfBirth\":\"13-02-1981\",\"yearOfBirth\":1981,\"ancestry\":\"\",\"eyeColour\":\"grey\",\"hairColour\":\"blonde\",\"wand\":{\"wood\":\"\",\"core\":\"\",\"length\":\"\"},\"patronus\":\"hare\",\"hogwartsStudent\":true,\"hogwartsStaff\":false,\"actor\":\"Evanna Lynch\",\"alive\":true,\"image\":\"http://hp-api.herokuapp.com/images/luna.jpg\"}]}"
}
Deploying to AWS
If that works, we can deploy:
serverless deploy
The Serverless Toolkit
will now hand over our function to AWS
using the infrastructure requirements we provided in our serverless.yml
. When successfully finished, we should see this information in our terminal:
Under the endpoints
output, we can see the (API Gateway
-) generated URL we need to invoke our function. The path /dev/house
not only contains the trailing /house
as specified in our serverless.yml
but also contains /dev/
as Serverless deploys to the dev
environment by default (we could also deploy to production by using the --stage
flag: serverless deploy --stage prod
).
Now, we can check if all files have been deployed to Lambda
successfully. In our AWS Management Console, we search for Lambda
and select getRandomHouseAndHousemates
. We should see something like this:
Testing the Endpoint
We can try out our endpoint by simply copying it from the terminal and paste it into the address bar of our browser.
If we use Postman, we get a neater looking result:
Now that our serverless function is up and running, we could access our newly created API from any web application (I'm planning to build a Sorting Hat App with React and TypeScript, but this is another story...).
Find the completed code of this Random Sorting Service on GitHub.
Top comments (0)