Lukas Polak
Posted on April 4, 2021
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.
git 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:
// pages/index.tsx
export default function Home() {
return (
<div>
<h1>Hello, Vercel!</h1>
</div>
)
}
To keep our changes more granular I'm committing here as well
git 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:
const customer = {
index,
name: faker.name.findName(), // generate the fake name
city: faker.address.city(), // generate the fake city
}
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).
// pages/api/customers.tsx
import faker from 'faker'
export default (req, res) => {
const customers = [...new Array(10)].map((_, index) => {
return {
index,
name: faker.name.findName(),
city: faker.address.city(),
}
})
res.status(200).json(JSON.stringify(customers))
}
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
.
const 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.
// pages/index.tsx
import { useEffect, useState } from 'react'
export default function Home() {
const [data, setData] = useState(null)
useEffect(() => {
const fetchData = async () => {
const response = await fetch('/api/customers', {
method: 'POST',
body: JSON.stringify({
limit: 100,
}),
})
return response.json()
}
fetchData().then((data) => {
setData(data)
})
}, [])
return (
<div>
<h1>Hello, Vercel!</h1>
{!data ? '...loading' : <pre>{JSON.stringify(data, null, 2)}</pre>}
</div>
)
}
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!
Posted on April 4, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
January 30, 2024