Understanding the Problem
In this phase, we need to set up the API routes for our Express application. The main purpose of our Express application is to serve as a REST API server, with all API routes beginning with the "/api/" prefix.
Our goal is to create a structured router setup that will allow us to organize our endpoints logically and test that the API routing system works correctly.
Planning the Solution
- Create an API router structure
- Connect the API router to the main router
- Add a test endpoint to verify that the API routing works
- Test the endpoint with fetch requests
Implementing the Solution
1. Create API Router Structure
First, let's create an api folder inside the routes folder and add an index.js file.
mkdir -p backend/routes/api
touch backend/routes/api/index.js
Add the following code to backend/routes/api/index.js to create a basic Express router:
// backend/routes/api/index.js
const router = require('express').Router();
module.exports = router;
2. Connect API Router to Main Router
Now, let's connect this API router to our main router in backend/routes/index.js. Update the file to include the API router:
// backend/routes/index.js
const express = require('express');
const router = express.Router();
const apiRouter = require('./api');
// Add a XSRF-TOKEN cookie
router.get("/api/csrf/restore", (req, res) => {
const csrfToken = req.csrfToken();
res.cookie("XSRF-TOKEN", csrfToken);
res.status(200).json({
'XSRF-Token': csrfToken
});
});
// Connect the API router
router.use('/api', apiRouter);
// Remove this test route since we're no longer using it
// router.get('/hello/world', function(req, res) {
// res.cookie('XSRF-TOKEN', req.csrfToken());
// res.send('Hello World!');
// });
module.exports = router;
By using router.use('/api', apiRouter), all routes defined in the API router will be prefixed with '/api'.
3. Add a Test Route to API Router
Let's add a test route to verify that our API router is working correctly. Update backend/routes/api/index.js to include a test POST route:
// backend/routes/api/index.js
const router = require('express').Router();
// Test route to check if API router is working
router.post('/test', function(req, res) {
res.json({ requestBody: req.body });
});
module.exports = router;
This route will accept POST requests to /api/test and respond with a JSON object containing the request body.
4. Test the API Router
Now that we have set up our API router, let's test it to make sure it's working correctly. Start your server if it's not already running:
cd backend
npm start
To test the API route, we need to make a POST request with a JSON body and include the CSRF token. Here's how to do it:
- First, open your browser and navigate to http://localhost:8000/api/csrf/restore to get a new CSRF token.
- Open your browser's developer tools (F12 or right-click > Inspect).
- Go to the Console tab.
- Look for the XSRF-TOKEN cookie in the Application tab > Cookies > localhost.
- Use the following fetch request in the console, replacing the XSRF-TOKEN value with your actual token:
fetch('/api/test', {
method: "POST",
headers: {
"Content-Type": "application/json",
"XSRF-TOKEN": `<value of XSRF-TOKEN cookie>`
},
body: JSON.stringify({ hello: 'world' })
}).then(res => res.json()).then(data => console.log(data));
If everything is set up correctly, you should see the following response in the console:
{ requestBody: { hello: 'world' } }
This confirms that your API router is working properly and can handle POST requests with JSON bodies.
Review the Solution
Let's review what we've accomplished in this phase:
- Created an API router structure that organizes all API endpoints under the /api prefix
- Connected the API router to the main router
- Added a test route to verify that the API routing system works
- Successfully tested the endpoint with a fetch request including CSRF protection
This API router structure will provide a solid foundation for adding more specific API endpoints in the future, such as user authentication routes, application-specific routes, and more.
Real-world Application
In real-world applications, this type of router structure is commonly used to organize API endpoints logically. For example:
- /api/users for user-related endpoints
- /api/products for product-related endpoints
- /api/orders for order-related endpoints
Each of these could have their own router file, making the codebase more maintainable and easier to understand.
Common Issues and Solutions
- CSRF Token Error: If you get a "invalid csrf token" error, make sure you're including the correct XSRF-TOKEN value in your fetch request headers.
- Route Not Found: If your route isn't being recognized, double-check the path and make sure the API router is properly connected to the main router.
- Missing JSON Body: If your request body isn't being parsed correctly, ensure you've included 'Content-Type': 'application/json' in your headers and that express.json() middleware is set up in your app.js file.
Next Steps
Now that you have set up the API routes for your application, you are ready to move on to Phase 2: Error Handling, where you will implement error-handling middleware to make your application more robust.
In the subsequent phases, we'll build upon this API router to add user authentication routes and other features.