Today, we will execute serverless RESTful API benefits by utilizing "Serverless Framework". There are many cloud administrations supplier offers serverless usefulness like AWS Lambda, Azure Functions, and Google CloudFunctions however in this article, I'm staying with AWS Lambda as a cloud specialist organization. 

On the off chance that you don't think about the serverless thought then I emphatically suggested that first checkout this video and return once completed it. 

Serverless Framework 

The serverless system is an open source CLI instrument that enables us to fabricate, design and convey serverless capacities (For our situation, AWS Lambda capacities). 

Without "Serverless Framework", we need to go physically on support at that point make and arrange important assets. That is alright when the venture is little and capacities are constrained yet when the undertaking develops then making and designing assets is a testing errand and in heaps of case unmaintainable. Composing code on comfort and overseeing group work process turns into a dreary activity. 

With a "Serverless Framework", we can rapidly construct, arrange and convey assets inside couple of directions. We can store our code and arrangement into a unified archive so we can outline appropriate work process and engineers can later compose, reuse and allude different designers codebase. 

There are heaps of critical points of interest of utilizing a serverless system as opposed to doing physically work. 

In this article, we will manufacture a serverless Pokemon RESTful API administrations with a "Serverless Framework". Checkout underneath table for reference.

Prerequisites
Install the following tools and frameworks:

Node.js 8.10 or above
MySQL
Visual Studio Code (preffered) or any code editor
Postman
Next, create the project folder and initialize it using npm.

mkdir pokemon-app
cd pokemon-app
npm init -f

Dependencies
Install the following packages to work with "Serverless Framework"

express - Fast, unopinionated, minimalist web framework for Node.js.
body-parser - Parse incoming request bodies in a middleware before your handlers, available under the req.body property.
mysql - A pure node.js JavaScript Client implementing the MySql protocol.
serverless - Framework for operationalize serverless development.
serverless-http - Plugin allows you to wrap express API for serverless use.
serverless-offline - Plugin to emulate AWS Lambda and API Gateway for speed up local development.

First up, we’ll install the serverless CLI:

npm install -g serverless

Now, let's install plugins and libraries step by step.

npm install express body-parser mysql serverless-http --save # app dependancies
npm install serverless-offline --save-dev # development dependancies
App structure
Before we start writing the handler code, we’re going to structure the project folder and configure our tools.

Create the following structure at the root level:

/pokemon-app/
|--/configs
|----/dbConfig.js
|--/node_modules
|--.gitignore
|--index.js
|--package.json
|--serverless.yml

What is ExpressJS

serverless.yml file serves as a manifest for our RESTful api service. Where we define our functions, events, and necessary resources. Later, with serverless CLI we configure and deploy our service to AWS infrastructure.

# serverless.yml
service: pokemon-service

provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: us-east-1
  memorySize: 512

functions:
  pokemonFunc:
    handler: index.handler
    events:
      - http:
          path: pokemon
          method: get
      - http:
          path: pokemon/{id}
          method: get
      - http:
          path: pokemon
          method: post
      - http:
          path: pokemon/{id}
          method: put
      - http:
          path: pokemon/{id}
          method: delete

plugins:
  - serverless-offline

  We are doing a few things here:

service: pokemon-service is a name of the service. You can give any type name for your service.
provider: This is where we specify the name of the provider we’re using (AWS as cloud service provider) and configurations specific to it. In our case, we’ve configured the runtime (Node.js) with 8.10 version and region to us-east-1.
functions: We specify the functions provided by our service, Here I'm specifying pokemonFunc as function name with http events. We can also say that this is our AWS Lambda function.
We have to store our pokemon somewhere, for sake of simplicity I'm chosen MySQL but you can also use another type database. I have already created a database with name pokemon_db and inside a database created table pokemon_tb with id, name, height, weight, avatar, and createAt columns.

CREATE TABLE `pokemon_tb` (
  `id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `height` float NOT NULL,
  `weight` float NOT NULL,
  `avatar` varchar(255) NOT NULL,
  `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `pokemon_tb` ADD PRIMARY KEY (`id`);

ALTER TABLE `pokemon_tb` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;

Rather than creating and managing connections every time, we configure pool connections once inside dbConfig.js file and reused it multiple times.

// dbConfig.js
const mysql = require('mysql')
const pool  = mysql.createPool({
  host            : 'localhost',
  user            : 'root',
  password        : '12345',
  database        : 'pokemon_app_db',
})

module.exports = pool

Writing the handler function
Let's focus on handling RESTful api route inside the index.js file with express. First, we imported the serverless-http package at the top. Second, we exported a handler function which is our application wrapped in the serverless package.

REST API Your Guide to Getting Started Quickly

Here, we're implementing basic five routes for handling crud operation with pokemon (without any validation).

const express = require('express')
const serverless = require('serverless-http')
const bodyParser = require('body-parser')
const pool = require('./configs/dbConfig')

const app = express()

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))

// Handle pokemon GET route for all pokemon
app.get('/pokemon/', (req, res) => {
  const query = 'SELECT * FROM pokemon_tb'
  pool.query(query, (err, results, fields) => {
    if (err) {
      const response = { data: null, message: err.message, }
      res.send(response)
    }

    const pokemons = [...results]
    const response = {
      data: pokemons,
      message: 'All pokemons successfully retrieved.',
    }
    res.send(response)
  })
})

// Handle pokemon GET route for specific pokemon
app.get('/pokemon/:id', (req, res) => {
  const id = req.params.id
  const query = `SELECT * FROM pokemon_tb WHERE id=${id}`
  pool.query(query, (err, results, fields) => {
    if (err) {
      const response = { data: null, message: err.message, }
      res.send(response)
    }

    const pokemon = results[0]
    const response = {
      data: pokemon,
      message: `Pokemon ${pokemon.name} successfully retrieved.`,
    }
    res.status(200).send(response)
  })
})

// Handle pokemon POST route
app.post('/pokemon/', (req, res) => {
  const { name, height, weight, avatar } = req.body

  const query = `INSERT INTO pokemon_tb (name, height, weight, avatar) VALUES ('${name}', '${height}', '${weight}', '${avatar}')`
  pool.query(query, (err, results, fields) => {
    if (err) {
      const response = { data: null, message: err.message, }
      res.send(response)
    }

    const { insertId } = results
    const pokemon = { id: insertId, name, height, weight, avatar }
    const response = {
      data: pokemon,
      message: `Pokemon ${name} successfully added.`,
    }
    res.status(201).send(response)
  })
})

// Handle pokemon PUT route
app.put('/pokemon/:id', (req, res) => {
  const { id } = req.params
  const query = `SELECT * FROM pokemon_tb WHERE id=${id} LIMIT 1`
  pool.query(query, (err, results, fields) => {
    if (err) {
      const response = { data: null, message: err.message, }
      res.send(response)
    }

What is NodeJS?

    const { id, name, height, weight, avatar } = { ...results[0], ...req.body }
    const query = `UPDATE pokemon_tb SET name='${name}', height='${height}', weight='${weight}', avatar='${avatar}' WHERE id='${id}'`
    pool.query(query, (err, results, fields) => {
      if (err) {
        const response = { data: null, message: err.message, }
        res.send(response)
      }

      const pokemon = {
        id,
        name,
        height,
        weight,
        avatar,
      }
      const response = {
        data: pokemon,
        message: `Pokemon ${name} is successfully updated.`,
      }
      res.send(response)
    })
  })
})

// Handler pokemon DELETE route
app.delete('/pokemon/:id', (req, res) => {
  const { id } = req.params
  const query = `DELETE FROM pokemon_tb WHERE id=${id}`
  pool.query(query, (err, results, fields) => {
    if (err) {
      const response = { data: null, message: err.message }
      res.send(response)
    }

    const response = {
      data: null,
      message: `Pokemon with id: ${id} successfully deleted.`,
    }
    res.send(response)
  })
})

// Handle in-valid route
app.all('*', function(req, res) {
  const response = { data: null, message: 'Route not found!!' }
  res.status(400).send(response)
})

// wrap express app instance with serverless http function
module.exports.handler = serverless(app)

Deployment
Deloying services with serverless framework is so simple, we require to just hit deploy command.

serverless deploy
I have not setup a MySQL database on my AWS account hence RESTful services will not work on my AWS infrastructure. Later, I will deploy RESTful services to AWS infrastructure.

Conclusion
Creating RESTful API with a serverless framework is pretty straightforward. For serverless, we have to switch our development workflow. I found that lots of companies are moving towards creating and managing micro-services architecture instead of the monolithic app. That's sound great.

You can Read Also:

50 recommended frameworks for nodejs