Setting Up Our API Server with AdonisJs Framework | Full-Stack Google Contacts Clone with AdonisJs (Node.js) and Quasar Framework (Vue.js)

Setting Up Our API Server with AdonisJs Framework | Full-Stack Google Contacts Clone with AdonisJs (Node.js) and Quasar Framework (Vue.js)

ยท

7 min read

In the last lesson, we discussed why we chose AdonisJS over other Node.js frameworks. In this lesson, we will setup the AdonisJS framework as our API server for this Google Contacts Clone App project.

If you are following along this series, you already have the initial installation (as seen here) of the AdonisJS Framework in the api folder of our project. Now, we have to install some extra packages and then test our API server.

Start by creating a new branch of your project.

git checkout -b 10-api-server-setup

Install and Configure the Lucid package

The Lucid package is used for interacting with the database. It offers a complete suite of SQL functionalities including querying, inserting, deleting, and updating records. It also offer a fluent ORM for interacting with database records, seeding, migrating tables, and working with model factories.

  1. Install the Lucid package:

    yarn add @adonisjs/lucid
    
  2. Configure Lucid:

    node ace configure @adonisjs/lucid
    
    1. When asked to Select the database driver you want to use, select MySQL / MariaDB.
    2. When asked to Select where to display instructions, choose Browser. If the browser does not launch, repeat: node ace configure @adonisjs/lucid and choose Terminal.
    3. When the configuration is done, follow the instructions on the terminal or browser. It is explained below.
  3. Open api/env.ts. Add the following to the options object of the Env.rules() function:

    DB_CONNECTION: Env.schema.string(),
    MYSQL_HOST: Env.schema.string({ format: 'host' }),
    MYSQL_PORT: Env.schema.number(),
    MYSQL_USER: Env.schema.string(),
    MYSQL_PASSWORD: Env.schema.string.optional(),
    MYSQL_DB_NAME: Env.schema.string(),
    

Install and Configure the Auth package

The Auth package provides authentication functionalities whether you are using AdonisJS as an API server or for server-side rendering of your web application.

  1. Install the Auth package:

    yarn add @adonisjs/auth
    
  2. Configure the Auth package:

    node ace configure @adonisjs/auth
    
    1. When asked to Select provider for finding users, select Lucid (Uses Data Models).

    2. When asked to Select which guard you need for authentication, select API tokens.

    3. When asked to Enter model name to be used for authentication, enter: User.

    4. When asked to Create migration for the users table, press y.

    5. When asked to Select the provider for storing API tokens, select Redis.

    Lucid will complete the setup of the package.

Testing our API server

We will change into our api directory, start the server, and ping the base route ("/") of the API server.

Don't type the # symbol and content after the # on each line

cd api # <-- change into our `api` directory
node ace serve --watch # <-- start the server
curl 127.0.0.1:3333/ # <-- ping the "/" route
{"hello":"world"}  # <-- response

The response came from the api/start/routes.ts file. Let's inspect that. Press CTRL+P on your keyboard and type api routes to search for the file. Click enter to open the api/start/routes.ts file as seen in the first result.

The file currently contains one route definition after the Route class is imported:

import Route from '@ioc:Adonis/Core/Route'

Route.get('/', async () => {
  return { hello: 'world' }
})

The first argument of the Route.get() method is the route path. In this case, the path is /. The second argument is an async function handler which simply returns an object: { hello: 'world' }. That's what we received on the terminal.

Read extensively about the AdonisJS routing here.

The route definition calls a static get method on the Route class. The get method corresponds to the HTTP GET request method. There are other static methods such as Route.post, Route.put, Route.delete, Route.post, and Route.patch. Their usage depends on the API operation you want to perform. Typically, you should follow this rules:

HTTP MethodAdonisJS Route MethodUsage
GETRoute.get()Use this method when you want to fetch (read) information about a entity. For example: fetching the details of a user.
POSTRoute.post()Use this method when you want to create a new entity. For example: create a new user.
PUTRoute.put()Use this method when you want to edit/override all the properties of an entity. For example: if you have five properties for a user and you want to edit all the five properties.
DELETERoute.delete()Use this method when you want to delete an entity. For example: deleting a user from the users table.
PATCHRoute.patch()Use this method when you want to partially edit/override some properties of an entity. For example: changing only the first_name and last_name while other properties remain unchanged.

Health Check

AdonisJS comes with a health checker for checking if our application is running optimally. It is often used by deployment tools to check if our application is running optimally before and after a new deployment. To add health check, do the following:

  1. Open api/start/routes.ts. Press CTRL+P on your keyboard and type api routes to search for the file. Click enter to open the file as seen in the first result.

  2. Below the import statement for the Route class, add: import HealthCheck from '@ioc:Adonis/Core/HealthCheck'

  3. Below the route definition for the path /, add:

Route.get('health', async ({ response }) => {
  const report = await HealthCheck.getReport()

  return report.healthy ? response.ok(report) : response.badRequest(report)
})

This adds the health route via the Route.get() method. It calls the HealthCheck.getReport(). The report object contains a boolean property: healthy. If healthy is true, we use the response.ok() method to return the report. Else, we use the response.badRequest() method to return a 400 error with the report as the payload.

Your api/start/routes.ts should look like this:

import Route from '@ioc:Adonis/Core/Route'
import HealthCheck from '@ioc:Adonis/Core/HealthCheck'

Route.get('/', async () => {
  return { hello: 'world' }
})

Route.get('health', async ({ response }) => {
  const report = await HealthCheck.getReport()

  return report.healthy ? response.ok(report) : response.badRequest(report)
})

Save the file. And ping the health route:

curl 127.0.0.1/health
# result below
{"healthy":true,"report":{"env":{"displayName":"Node Env Check","health":{"healthy":true}},"appKey":{"displayName":"App Key Check","health":{"healthy":true}}}}

Read more about AdonisJS health checks here.

Configuring the Database Credentials for the API Server

Now, we will pass in the database credentials we created two lessons ago. Open our .env file for our backend i.e. api/.env The .env file is an environment file which contains very import key-value pairs for our application.

More about the .env file. As you can see from the file, it contains the APP_KEY, MYSQL_USER, MYSQL_PASSWORD, and MYSQL_DB_NAME. These are very sensitive data for our backend which should not be known to any third party. This is the reason why you should never commit your .env into GitHub or other version control systems. As a matter of fact, AdonisJS has a file api/.gitignore which already configures the .env file to be ignored by git during commits.

The APP_KEY value is used as the encryption salt for your application. All encryptions and hashing are done on the basis of the APP_KEY. It should be very random and never shared across multiple applications. If you need to change the APP_KEY, run:

node ace generate:key

Then copy the generated key from the terminal into the .env file replacing the old value for APP_KEY.

SERIOUS WARNING. Updating the APP_KEY for an existing application with users will invalidate all passwords (passwords are hashed) and encrypted data. You should only do this in production in the case of a security breach, in which case, you will inform your users to reset their passwords.

Back to configuring our database credentials:

  1. For MYSQL_HOST, change the value to; 127.0.0.1.
  2. For MYSQL_USER, change the value to: google_contacts_clone_user.
  3. For MYSQL_PASSWORD, change the value to the password you chose.
  4. For MYSQL_DB_NAME, change the value to: google_contacts_clone_app
  5. If you did use the default port number of 3306 when installing the MySQL database server, change the value for MYSQL_PORT to that port number you assigned.

Save and close the file.

Testing the Database Connection

Open api/config/database.ts file.

Within the mysql property, change healthCheck to true.

{
  pg: {
    client: 'pg',
    connection: {
      // ... connection details
    },
    healthCheck: true, // ๐Ÿ‘ˆ enabled
  }
}

Save and close the file.

Now, ping the health route again. You will get:

curl 127.0.0.1/health
# result below
{"healthy":true,"report":{"env":{"displayName":"Node Env Check","health":{"healthy":true}},"appKey":{"displayName":"App Key Check","health":{"healthy":true}},"lucid":{"displayName":"Database","health":{"healthy":true,"message":"All connections are healthy"},"meta":[{"connection":"mysql","message":"Connection is healthy","error":null}]}}}

The Database health check is healthy.

If all is going well as shown here, congratulations. Our API server is ready to serve our Google Contacts Clone App.

Save all your files, commit and merge with the master branch.

git add .
git commit -m "feat(api): complete API Server setup"
git push --set-upstream origin 10-api-server-setup
git checkout master
git merge master 10-api-server-setup
git push

In this next lesson, we will setup Postman and get it ready for real work.

ย