Using faker.js on Next.js API route

April 4, 2021
Open GitHub repositoryOpen deployed app

Next.js provides a neat functionality to create API routes. Any file inside pages/api will be treated as an API endpoint instead of a page.

So let's create an API endpoint with dynamic faker.js data.

First, we need to initialize a Next.js app - yarn create next-app faker-js-on-next-js-api-route command is here to rescue! And because I prefer a type safety and I like TypeScript, we will initialize it as well.

With touch tsconfig.json (file will be populated after running yarn run dev command), we will create a config file for TypeScript. With yarn add --dev typescript @types/react, we will install all the dependency that we will need.

The next thing that we need to do is rename every file extension from .js to .tsx. After renaming, we can stage our files and commit them.

1git add -A && git commit -m "initialize typescript"

Our project has styles that we will not need for this kind of project, so I will remove the styles folder and Remove .css imports from pages/_app.tsx and pages/index.tsx files. Also, I have removed all the unnecessary code from the pages/index.tsx file, so it looks like this:

1// pages/index.tsx
2
3export default function Home() {
4 return (
5 <div>
6 <h1>Hello, Vercel!</h1>
7 </div>
8 )
9}

To keep our changes more granular I'm committing here as well

1git add -A && git commit -m "remove styles"

Next, we will rename pages/api/hello.tsx to pages/api/customers.tsx and we will install faker.js dependecy with yarn add faker and type definitions with yarn add @types/faker -D

Now, let's edit our customers.tsx file. We need to import a faker instance and then default export our function, which accepts req (An instance of http.IncomingMessage) and res(An instance of http.ServerResponse) parameters. Both req and res have some helper functions and middlewares on top of the HTTP classes.

To generate customers, we need to create an empty new array. To the arrayLength parameter, we will pass 10 (We will make this dynamic later on). Then we need to spread the newly created array to an empty array to make it iterable. Then we are going to map through this array. We will omit the value parameter by passing the _, and we will use the index to see the current index of the object. We will return an object which will look like this:

1const customer = {
2 index,
3 name: faker.name.findName(), // generate the fake name
4 city: faker.address.city(), // generate the fake city
5}

Last but not least, we need to set the response status to 200 (OK) and then return a JSON response with our customer's data (we need to stringify customers object with the JSON.stringify() method).

1// pages/api/customers.tsx
2
3import faker from 'faker'
4
5export default (req, res) => {
6 const customers = [...new Array(10)].map((_, index) => {
7 return {
8 index,
9 name: faker.name.findName(),
10 city: faker.address.city(),
11 }
12 })
13
14 res.status(200).json(JSON.stringify(customers))
15}

If we go to http://localhost:3000/api/customers (If you are using a different port replace this URL), we will see that we get the data.

Now let's make the data more dynamic, at least the length. Instead of hardcoded arrayLength, we will receive a limit from the request body (if limit won't be provided, we will use fallback value, e.g. 10).

First, we need to define a limit constant and check if it was provided in the body. If not, we will use 10.

1const limit = JSON.parse(req.body)?.limit ?? 10

Then we can safely replace [...new Array(10)] with [...new Array(limit)]

After this refactoring, you can test it with Postman, Insomnia, or your other favorite tool, or you can stay with me for a little bit longer and test it within the app.

Inside the pages/index.tsx file, We will create a state for our data. We will use the useEffect hook that will be run only on the initial mount (empty dependency array). Within useEffect we will create an async fetchData function that will fetch our /api/customers api endpoint. We will pass a stringified object with our limit key to the body of the' fetch' function options. Then we will return a JSON representation of the response. Next, we will call the fetchData function, and in the then method we will set the state with incoming data.

I'm not handling errors here for simplicity, and I'm assuming that if there is no data in the state, the state should be loading.

1// pages/index.tsx
2
3import { useEffect, useState } from 'react'
4
5export default function Home() {
6 const [data, setData] = useState(null)
7
8 useEffect(() => {
9 const fetchData = async () => {
10 const response = await fetch('/api/customers', {
11 method: 'POST',
12 body: JSON.stringify({
13 limit: 100,
14 }),
15 })
16
17 return response.json()
18 }
19
20 fetchData().then((data) => {
21 setData(data)
22 })
23 }, [])
24
25 return (
26 <div>
27 <h1>Hello, Vercel!</h1>
28 {!data ? '...loading' : <pre>{JSON.stringify(data, null, 2)}</pre>}
29 </div>
30 )
31}

And that's it! Pretty simple right? Hopefully, you find this article, and feel free to contact me if you have any questions or feedback!

See you next time!