Today we are going to build a simple API using Next.js, then use Vercel platform, to deploy it online.

Next.js is a React framework by Vercel, that comes with server-side rendering out of the box. It is quite extensible and has minimal setup. Perfect for small and quick projects, such as this one!

What we want to achieve is create an API that takes a string and renders given string as a beautiful ASCII art (using figlet library).

Project setup

We are going to setup a new repository and start with initializing a new project.

npm init -y

Now that we have package.json file in our project folder, let’s add some dependencies:

npm install next react react-dom figlet

One last thing to we need is some helper scripts! Let’s add these to our package.json:

  • next dev
  • next build
  • next start

Our finished package.json should look like this:

{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "figlet": "^1.5.0",
    "next": "^11.0.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  }
}

If we try to run npm run dev, we will see an error. That’s because we have to add some “pages”!

Let’s get coding

First, Next requires us to create pages/ directory to serve our app.

mkdir pages

This is enough to make it work. If we run npm run dev and navigate to localhost:3000, we will see a 404 page generated by Next.

Since we are working on REST API, we need a route that we can talk to. Inside our pages folder, lets add an api folder. This is where our API routes will live.

Inside api folder, let’s add an example route called figlet (by creating figlet.js file). As you may have noticed, API routes are named after files. This means that if we want to have localhost:3000/api/users route, we would create users.js inside our api folder.

Here is what the structure of our project folder should look like:

├── package.json
├── package-lock.json
└── pages
    └── api
        └── figlet.js

Time to populate figlet.js and see some magic:

export default function getFiglet(req, res) {
  res.status(200).json({ hello: 'world' })
}

When we run npm run dev, and point our browser at localhost:3000/api/figlet, we should get this JSON response:

{"hello":"world"}

Now that we know how to add a route, create lib folder in main directory. Inside lib add figlet-render.js file with this content:

import figlet from 'figlet'

export default function figletRender(str) {
  return figlet.textSync(str)
}

This module takes a string and returns it’s rendered form. Let’s import figlet-render.js inside figlet.js api route and modify our code:

import figletRender from '../../lib/figlet-render'

export default function getFiglet(req, res) {
  if (!req.body.text) {
    return res.status(400).json({ text: 'Error: Missing text' })
  }

  res.status(200).json({ text: figletRender(req.body.text) })
}

Let’s test it

If you’ve left dev server running in the background, it will automatically reload code and your application is ready to test. In case you didn’t, make sure the app is running with npm run dev.

Now that our application is finished and running, we have to see if it works!

curl -s -X POST -H "Content-Type: application/json" -d '{"text":"Hello World!"}' localhost:3000/api/figlet
{"text":"  _   _      _ _        __        __         _     _ _ \n | | | | ___| | | ___   \\ \\      / /__  _ __| | __| | |\n | |_| |/ _ \\ | |/ _ \\   \\ \\ /\\ / / _ \\| '__| |/ _` | |\n |  _  |  __/ | | (_) |   \\ V  V / (_) | |  | | (_| |_|\n |_| |_|\\___|_|_|\\___/     \\_/\\_/ \\___/|_|  |_|\\__,_(_)\n                                                       "}

By querying the api, we will get garbled text. That happens, because we see it as one continuous string of text (notice ‘\n’ characters not being rendered as newline). We can fix this with a little bash magic (make sure you have ‘jq’ installed, as it might not be available on some systems out of the box).

curl -s -X POST -H "Content-Type: application/json" -d '{"text":"Hello World!"}' localhost:3000/api/figlet | jq .text | xargs printf
  _   _      _ _        __        __         _     _ _
 | | | | ___| | | ___   \ \      / /__  _ __| | __| | |
 | |_| |/ _ \ | |/ _ \   \ \ /\ / / _ \| '__| |/ _` | |
 |  _  |  __/ | | (_) |   \ V  V / (_) | |  | | (_| |_|
 |_| |_|\___|_|_|\___/     \_/\_/ \___/|_|  |_|\__,_(_)

If we don’t send any text, we get a nice error message:

curl -s -X POST localhost:3000/api/figlet | jq .text | xargs printf
Error: Missing text

Our API is working correctly. It’s time to show it to the world!

Deployment

For quick and simple projects like this, I use Vercel to deploy my APIs. Let me show you how easy it is.

  1. Go to vercel.com and log in with your Gitlab/Github account (Vercel will request authorization).

  2. Select the correct team and repository.

    Vercel - Select repository

  3. Import project into vercel. All required fields will be filled out for you. Notice how vercel automatically detects Next.js framework. All that’s left to do at this point is to click “Deploy”. Vercel will attach a pipeline to your repository and build the API!

    Vercel - Import repository

  4. Once it’s done, click on “Open Dashboard” to see you deployment.

    Vercel - Dashboard

    Dashboard will include a link to deployed API. Let’s test it (keep in mind your url will be different):

curl -L -s -X POST -H "Content-Type: application/json" -d '{"text":"Hello World!"}' https://test-figlet-3ntb05xk4-mmrowiec.vercel.app/api/figlet | jq .text | xargs printf

And here is our rendered text:

  _   _      _ _        __        __         _     _ _
 | | | | ___| | | ___   \ \      / /__  _ __| | __| | |
 | |_| |/ _ \ | |/ _ \   \ \ /\ / / _ \| '__| |/ _` | |
 |  _  |  __/ | | (_) |   \ V  V / (_) | |  | | (_| |_|
 |_| |_|\___|_|_|\___/     \_/\_/ \___/|_|  |_|\__,_(_)

Conclusion

As you can see, with a minimal setup and few lines of code, we’ve created and deployed an API that takes a string and returns it as an ASCII art.

We’ve used Vercel platform for deployment, but there are other services that provide similar functionality, such as AWS Amplify or Netlify.

Now that the API is working, you can use it as a Slack command (or whatever other communication software your team is using) and make your coworkers jealous!