Remaking the API
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
This lesson preview is part of the Fullstack React with TypeScript Masterclass course and can be unlocked immediately with a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Fullstack React with TypeScript Masterclass with a single-time purchase.

[00:00 - 00:09] Remaking API. Now our project has a separate server in the server folder. With the Versal we no longer need it because of the serverless functions.
[00:10 - 00:19] To create serverless function we need to use next's API routes. Serverless functions, here, are a wrapper on the file system or a third party server.
[00:20 - 00:27] Conceptually these API routes are very similar to what we did in the server directly. The difference is that with API routes we need to change the routing model.
[00:28 - 00:46] Previously we used Express to define routes and handlers for them. With the next.js API routes we need to create the API directory inside pages, pages, create new folder, API, and use directories and files to define routes, just like with the ordinary next pages.
[00:47 - 00:56] So let's say we have the API folder inside of the pages folder and let's define our Hello World controller. Create new file, Hello.ts.
[00:57 - 01:10] Here we import type next API request next API response from next. And then we export default function Hello.
[01:11 - 01:30] This function will receive request of type next API request and response of type next API response. This function will response with status 200 which means OK and JSON with field Hello and text World.
[01:31 - 01:39] Just like with regular next pages we export the function from the module. But this time instead of a page we export an API controller that takes two arguments.
[01:40 - 01:47] Request and response. Request is an instance of HTTP incoming message with a bunch of pre-built middle layers.
[01:48 - 01:57] It is conveniently typed with next API request type. Response is an HTTP server response with next response helpers.
[01:58 - 02:02] It is typed with the next API response type. Here we are using import type.
[02:03 - 02:12] And it is a new feature in TypeScript 3.8 that allows type only imports and export. Nothing fancy it just means that we only import a type.
[02:13 - 02:23] By default the API routes handle get requests. So if we go now to local host 3000 API Hello we will see the API response Hello world.
[02:24 - 02:28] Hooray we made our first API controller. Now remove the Hello TS we don't need it anymore.
[02:29 - 02:35] It was there only to demonstrate how controllers work. And let's rebuild all our existing APIs using API routes.
[02:36 - 02:39] Remaking posts. Let's start with remaking posts.
[02:40 - 02:48] Here we have two endpoints. API posts for getting the list of all posts and API posts ID for getting a particular post by its ID.
[02:49 - 02:58] We put the first handler into pages API posts index dot TS. Here is going to be a function called post handler.
[02:59 - 03:03] It doesn't really matter how you call those functions. You expert them as default anyway.
[03:04 - 03:11] So call them however you find them the most readable. Here we get the post from the post source in our case is just a Jason.
[03:12 - 03:22] We cast it to post array because we don't get the type information from the Jason files right. And then we return status 200 and Jason of those post array.
[03:23 - 03:32] Now if you go to local host API posts we should get a response with all the posts in that file. Okay getting the list of posts was pretty straightforward.
[03:33 - 03:38] But what if we need to define a dynamic route. The second controller that takes a particular post is exactly this case.
[03:39 - 03:44] To respond with a particular post we need to know what ID was required. For this next offers the same model as with pages.
[03:45 - 03:52] We can use dynamic API routes. So let's create a new file square brackets ID dot TS.
[03:53 - 03:58] Here we'll define an individual post handler. It will still get the posts list from the Jason.
[03:59 - 04:11] It will get the wanted ID from the query ID this query field exists on the request object. And it will have the segment name in our case ID that we defined in the name of our file.
[04:12 - 04:20] Then we get the post by finding it in the list of posts. We did exactly the same in our old express.js implementation.
[04:21 - 04:26] You can see it here. And after we got it we return status 200 and Jason of this post.
[04:27 - 04:32] Let's try it out. Go to API posts for and you should receive the data for this post.
[04:33 - 04:36] Remaking categories. For categories we also have two end points.
[04:37 - 04:46] API categories for getting the list of categories and API categories ID for getting posts for the category. Inside of the API create a new folder categories.
[04:47 - 04:56] And then inside of it let's create new file index dot TS. In this file we'll define the categories handler that will get the categories from the Jason.
[04:57 - 05:03] Categories Jason. And then we'll return status 200 encoding the categories as a Jason again.
[05:04 - 05:10] Same as with posts create a new file that will handle the individual category. Square brackets ID TS.
[05:11 - 05:20] And here we'll define category handler that will find the posts for the given category. We will look through the posts and filter them by the category ID.
[05:21 - 05:29] Looking for one that matches that with the ID that we got from the query. Here I repeat the contents of the found three times.
[05:30 - 05:40] Just so that the categories don't look too empty because we don't really have too many posts defined in those Jason files. After we have the category posts we return them as a Jason.
[05:41 - 05:45] Remaking comments. We will need only one end point for working with comments but it will handle two different methods.
[05:46 - 05:53] Get and post. There will be one method get API comments by post ID for getting the comments for a given post.
[05:54 - 06:00] And post API comments post ID for submitting a comment for a given post. Let's start with getting comments for a post.
[06:01 - 06:04] Inside of the API we'll need a new folder. Comments.
[06:05 - 06:09] And here we'll define a new file ID TS. Add the imports.
[06:10 - 06:17] Here we define the comments as an array of comments. And then we define a function comments for post.
[06:18 - 06:21] Here we receive a post ID. It's going to be entity ID.
[06:22 - 06:28] And we return comments filter. And here we'll filter the comments by the post post.
[06:29 - 06:36] And we compare the post with the post ID from the params. This is our helper function to get the comments for the particular post.
[06:37 - 06:42] And now let's define the comments handler. Expert default function comments.
[06:43 - 06:49] Andler is going to receive request. Next API request and response.
[06:50 - 06:59] Next API response. Here we'll get the post ID const post ID equals a number from request query ID.
[07:00 - 07:04] Then we'll switch depending on the request method. Switch request method.
[07:05 - 07:12] Here if it's a get method case get we'll return response status. 200.
[07:13 - 07:20] JSON. And here we return the comments for the post comments for post and we pass the post ID.
[07:21 - 07:32] Otherwise case post we're going to push a new comment to the comments array. Comments push ID comments length plus one.
[07:33 - 07:40] It's a very naive way of generating IDs. We'll just increment them with every new comment author request body name.
[07:41 - 07:56] Content request body comment post post ID and time less than a minute ago. And as you can see the red underline disappeared only after I've added the time property.
[07:57 - 08:03] That's because we've typed the comments as an array of comment type. Alright, we have the comments updated.
[08:04 - 08:09] Let's write them to the file. In real app you'd probably write it into the database instead of updating the JSON.
[08:10 - 08:23] Alright, file path resolve from process CVD and we add server comments JSON to it. As a data we use JSON stringify comments.
[08:24 - 08:40] Alright, after it's done we return response JSON comments for post for the given post ID. Don't forget to add the default case.
[08:41 - 08:47] This should get to the post case and then default means that we return response status 404. So if it's not get and not post then we don't know how to process it.
[08:48 - 08:48] Format the document.