Build an API for a Marvel Movie Directory Using Node.js
Published: 2023-07-03 16:01:00

Want to expand your portfolio and brush up on your dev skills? Follow along with our guide to spinning up an API for an MCU movie directory using Node.js. 

## Step 1: Set up Your Framework 
[Fastify](https://www.fastify.io/) is a great Node.js framework built with performance and developer experience in mind. It's well maintained, has frequent releases, excellent documentation, and the plugin system allows for great extensibility. We would recommend using it for this project. 

After you have installed Node.js and Fastify, ensure your server is working correctly and that it has a route `/` that replies back the text “Hello Kinsta”.


**Quick tip: if you want to deploy your application don’t forget to use the environment variable “PORT”**


> Plus need some more help? Check out [this guide](https://www.fastify.io/docs/latest/Guides/Getting-Started/)



## Step 2: API Integration 

Next, let’s look at [TypeScript](https://www.typescriptlang.org/) and third-party API integration… 


First, why TypeScript? Its adoption has been growing remarkably and its developer experience is quite enjoyable. The tooling around it has matured into many polished and highly popular tools, libraries, and utilities. 

In this case, the third-party API will be the one that already contains all the MCU movies, and you will have to make a request in your application to retrieve that information.

You can read its documentation [here](https://mcu-qdh4b.kinsta.app/docs).

To pass this step we want to be able to search movies by making a request to our application by using the third-party API. For this, you will need to add a route `/movies` that would make a request to the `https://mcu-qdh4b.kinsta.app/api/v1/movies` endpoint. 

Your route should forward the following parameters of the querystring: filter, page, limit, and order.

To test your endpoint, making a request `/movies?page=1&limit=10&order=chronology%2CDESC&filter=title%3DIron` should return a list of all three Iron Man movies. 

> **Need some more help? Check out these resources if you get stuck:**
> - https://www.typescriptlang.org/docs/
> - https://www.fastify.io/docs/latest/Reference/Routes/ 

**Quick tip:** Use types to your advantage to type the function parameters on your endpoints:


![Screenshot of code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2iydz4xp9r0yfjbv4swc.png)

## Step 3: PostgreSQL 
PostgreSQL is an Open Source database that is battle-tested and used by almost every company out there. ORMs are pretty helpful in abstracting away some of the hassle of generating database queries, and in this case, Prisma has excellent docs and a great TypeScript integration. 
First, install PostgreSQL and verify that it’s working correctly.

Then you will need to add Prisma to your application, which involves creating a `schema.prisma` file that defines PostgreSQL as datasource and describes two models: User and Movie. 

The model Movie should have a list of users as one of its fields. Once you’re done with your schemas, don’t forget to generate its types so that you can use them in your app.

Continue with adding a Fastify plugin that would connect to the database so that once your routes get a request the connection is already established. Use Fastify’s decorators to make the Prisma client available to all of your routes. 

Finally, add a route `/movies/add` that would receive a `userId` and a `movieId` in its request body and that uses Prisma to create a Movie record in the database associated with that `userId`.

> **Need some more help? Here are some useful docs:**
> - https://www.postgresql.org/download/
> - https://www.fastify.io/docs/latest/Reference/Plugins/
> - https://www.fastify.io/docs/latest/Reference/Decorators/
> - https://www.prisma.io/docs/concepts/components/prisma-client/crud#update
> - https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#update-or-create-a-related-record 


If you’re still stuck, check out this example of  “schema.prisma” file:


![schema prisma file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q3k7dnq6jsmus552alm6.png)



## Step 4: Testing


Unit testing is used throughout the industry to reduce the number of bugs that are introduced while coding. 
There are many testing methodologies (TDD, BDD, etc), but the consensus is that on every large application having unit tests is better than not having any tests at all. 
Mocks are useful when the code you need to test has external dependencies (like databases). In this case, you will need to mock Prisma so that your tests don’t rely on a database to be able to run.


To complete this step, use Jest to add tests for your `/movies` and `/movies/add` routes. Hint: your Fastify plugin that connects to the database and makes Prisma available as decorator should return a JavaScript function in order to be mocked properly. 


> **Check out these links for more info:**
> - https://www.fastify.io/docs/latest/Guides/Testing/#benefits-of-using-fastifyinject
> - https://www.npmjs.com/package/jest-mock-extended 


## Step 5: Schema Validation 

To help prevent malicious actors from triggering unvalidated logic or error messages that are hard to understand, it is important to have schema validation into your app. 
 There are multiple ways to integrate it: JSON schema, typebox, Joi, Zod, and others. In this step, we will use typebox for its convenience of translating JSON Schemas into types that we can use in TypeScript. 

Use typebox to define entities (like Movie and User) and parameters (querystring or request body) that will be used in your `/movies` and `/movies/add` routes. 


Lastly, if you want to improve response times and reduce load on services that your application uses then caching is key.


## Step 6: Wrapping Up 


Finally, add a simple in-memory cache for your `/movies` endpoint. Whenever a request is done, check if the cache has the results and if it's not cached then store it. Avoid using any external library for doing this. 


**Bonus points:** It would be great to limit the number of movies you can cache to avoid running out of memory. While there are many cache eviction strategies, using something like a least recently used strategy should be a nice improvement. 


> **Check out these links for more info:**
> - https://www.fastify.io/docs/latest/Reference/TypeScript/#typebox
> - https://www.npmjs.com/package/@sinclair/typebox
> - https://en.wikipedia.org/wiki/Cache_replacement_policies
> - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys 


And that’s it! You should now have a fully functional API for an MCU movie directory! Share your GitHub link below, and be sure to check out [Kinsta's Hobby Tier](https://kinsta.com/application-hosting/pricing/hobby-tier/) for easy application hosting for only $7/month.