API Server Setup with Express.js and TypeScript

Part 2: Creating a Model, Router and Controller

Ward Price
JavaScript in Plain English

--

On the last tutorial we created a very basic ‘Hello World’ implementation of Express.js. In this part of the series we will create a Model, Router and Controller. With the goal of creating a Movie lookup API.

Open up the app me we made in the last tutorial. If you’re just joining now you can clone down it down from my github, here.

Ok now we are ready to go, first lets install body-parser. Although we have a very simple server thus far, as we start adding requests to and from body-parser will make our lives much easier. It takes the raw request, extracts the data we will need to work with within our server and places that on the req.body.

Install bodyParser

In your terminal run the following command.

$ npm i body-parser

To incorporate this in with our server let’s import it by adding the this line to the top of our index.ts file.

import bodyParser from 'body-parser'

Now above the current app.get() statement we have add the following two commands.

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

So what does this do? app.use mounts the following function and will run the function if the path matches the specified path in the request. The function bodyParser.json() will parse the text in the request to json and mounts that object on to the req.body. The next line, bodyParser.urlencoded({ extended: true }) parses the text as URL encoded data and mounts the resulting object onto the req.body, this is most important for post requests as URL encoded data is how browsers send post requests from forms. For more info check out this Stack Overflow post.

Now we because we are going to add a router go ahead and remove this line.

app.use('/', (req, res) => {
res.send('Hello World!')
})

Initially setting up the Router

Create 3 folders inside the src folder, routes, controllers, models. We are going to create this api utilizing the MVC pattern, but of course without the views.

Inside the routes folder create the file index.ts. We will import express and then create the router and export it so that we can use it in src/index.ts.

import express from 'express'const router = express.Router()export default router

In the src/index.ts file import our newly created router.

import routes from './routes'

Just below the bodyParser statements add this line.

app.use(routes)

This router index doesn’t do anything yet but that is because we have nothing to route to! Let’s create our controller next.

I know this is kind of confusing that we now have two index.ts files but in Node.js when you import a folder to a component Node.js will look for an index.ts file if no file is specified. Furthermore, as you will see the routes/index.ts file we just created will act as a switchboard to the appropriate controller. More on that later…

Setting up the controller

Inside the controllers folder add a file name moviesController.ts. This file will handle the logic of what happens when a certain endpoint is accessed. Now, in this file we will have to import the types for express to use.

At the top of the file add…

import { Request, Response, NextFunction } from 'express'

Now to get this ready for our router let’s create our “Hello World” response again.

Create a function named getHello. We will create a normal synchronous function as this will be simple and pretty immediate. In the next part of this series we will add MongoDB as our database. It’s then we will make these functions asynchronous.

function getHello(req: Request, res: Response, next: NextFunction) {
res.send('Hello World!')
}

We must export this function to be used in our router. At the bottom of the file add the following…

export default { getHello }

Connect route to controller

Create a new file in the routes folder named movieRoutes.ts, import express and import the controller we just created as well as create a router as we did before in the routes/index.ts file.

import express form 'express'
import moviesController from '../controllers/movieController'
const router = express.Router()export default router

When we reach the '/' endpoint, I want it to return Hello World from our getHello function. Add the following line just before the export default router line.

router.get('/', movieController.getHello)

Alright, so close! Now all we need to do is incoporate this to routes/index.ts. Import the movieRoutes.ts file and then utilizing the router allow it to be used.

import movieRoutes from './movieRoutes'router.use('/api/v1/movies', movieRoutes)

Great! Now if we run npm start in the terminal. Then navigate to localhost:3000/api/v1/movies it should return Hello World!. We now have a much more modular and easier to maintain foundation.

You might ask yourself, why does did we create an routes/index.ts file then another router file for the moviesController? Well, this is building for the future. If ever the api was to drasticlly to a new version all we need to do is set that route in the routes file for that new movie controller. This seperates everything so it’s easier locate where to make the change quickly and efficiently.

Next time, we add MongoDB!

Full code to clone

Happy Coding!!

Tutorials in Series

Part 1: “Hello World!”

Part 2: Setting Up The Router

Part 3: Connecting to MongoDB

--

--