In this lesson, you'll learn how to build a simple API using Express.js and mock data. We'll cover setting up an Express.js server, creating mock data, writing endpoints, and retrieving data.
By the end of this lesson, you will:
- Set up an Express.js server
- Create mock data arrays
- Write POST endpoints for adding data
- Write GET endpoints for retrieving data
- Start your server
Here we'll learn to set up an Express.js server. This is crucial as it forms the backbone of our API, giving us a robust platform to build on.
JavaScript1const express = require('express'); // Import Express.js library 2 3const app = express(); // Create an instance of Express 4const PORT = 3000; // Port where the server will listen 5 6app.use(express.json()); // Middleware to parse JSON request bodies
To set up an Express.js server, we first need to import the Express library using require('express')
. Then, we create an instance of the Express application by calling express()
. We define a port number where the server will be listening for requests; in this case, it’s set to 3000. Additionally, we use a middleware function express.json()
which allows our server to parse JSON data in the request bodies. This setup is fundamental as it creates the environment where our API can live and function.
Let's move to creating mock data arrays. We do this to simulate a real-world scenario and not use a complex database. This is for learning purposes, and in real-life scenarios, you'll always be using real databases.
JavaScript1// Mock data 2const users = [ 3 { id: 1, name: 'John Doe', email: 'john@example.com' }, 4 { id: 2, name: 'Jane Doe', email: 'jane@example.com' }, 5 { id: 3, name: 'Sam Smith', email: 'sam@example.com' }, 6]; 7 8const posts = [ 9 { id: 1, title: 'First Post', content: 'This is the first post', userId: 1 }, 10 { id: 2, title: 'Second Post', content: 'This is the second post', userId: 2 }, 11]; 12 13const categories = [ 14 { id: 1, name: 'Tech', posts: [1] }, 15 { id: 2, name: 'Lifestyle', posts: [2] }, 16];
Instead of diving into database management, we create mock data to simulate real data. This step involves defining arrays for users
, posts
, and categories
. These arrays hold objects that represent typical data entities you would encounter in a real-world situation. For users
, each object contains an id
, name
, and email
. The posts
array includes id
, title
, content
, and userId
(to link posts to specific users). Lastly, the categories
array comprises id
, name
, and posts
(an array of post IDs under that category). Using mock data keeps things simple and focuses on learning the core concepts.
We'll now create POST endpoints to add data. This is critical for allowing our API to accept new data entries from users.
Creating a User:
We create a POST endpoint to handle adding new users to our system. This is essential for allowing user registrations and onboarding.
JavaScript1// Create a User 2app.post('/users', (req, res) => { 3 const { name, email } = req.body; 4 if (!name || !email) { 5 return res.status(400).json({ message: 'Name and email are required' }); 6 } 7 const newUser = { id: users.length + 1, name, email }; 8 users.push(newUser); 9 res.status(201).json(newUser); 10});
To add new users, we define the /users
endpoint using app.post()
. This endpoint expects a request body containing name
and email
. We first check if these fields are present using a simple validation. If either name
or email
is missing, we return a 400
status code with a relevant message. If the data is valid, we create a new user
object with a unique id
, add it to the users
array, and then return the newly created user along with a 201
status code indicating a successful creation.
Creating a Post:
We create a POST endpoint for adding new posts. This is important for allowing users to contribute content to the platform.
JavaScript1// Create a Post 2app.post('/posts', (req, res) => { 3 const { title, content, userId } = req.body; 4 if (!title || !content || !userId) { 5 return res.status(400).json({ message: 'Title, content, and userId are required' }); 6 } 7 const newPost = { id: posts.length + 1, title, content, userId }; 8 posts.push(newPost); 9 res.status(201).json(newPost); 10});
The process of adding posts is similar to adding users. Here, the /posts
endpoint is defined using app.post()
. It expects a request body containing title
, content
, and userId
. We validate these fields and if any are missing, a 400
status code is returned. If the data is valid, a new post
object is created with a unique id
, and the post is added to the posts
array. We then return the newly created post along with a 201
status code.
Creating a Category:
We create a POST endpoint for adding new categories. This is helpful for organizing posts into different groups.
JavaScript1// Create a Category 2app.post('/categories', (req, res) => { 3 const { name, posts } = req.body; 4 if (!name || !Array.isArray(posts)) { 5 return res.status(400).json({ message: 'Name and posts array are required' }); 6 } 7 const newCategory = { id: categories.length + 1, name, posts }; 8 categories.push(newCategory); 9 res.status(201).json(newCategory); 10});
For categories, the endpoint expects name
and posts
array in the request body. Similar validation is performed to ensure name
is provided and posts
is an array. If validation fails, a 400
status code is returned. Upon successful validation, a new category
object is created and added to the categories
array. The newly created category is then returned with a 201
status code.
Next, we’ll add GET endpoints to retrieve data. GET endpoints are important for fetching and displaying existing data to users.
Retrieve a Single Post with the User:
We create a GET endpoint for retrieving a single post along with the user who created it. This is useful for displaying detailed post information on your frontend.
JavaScript1// Retrieve a Post with the associated User 2app.get('/posts/:id', (req, res) => { 3 const post = posts.find(p => p.id === parseInt(req.params.id)); // Find post by ID 4 if (!post) res.status(404).send('Post not found'); // Handle not found 5 6 const user = users.find(u => u.id === post.userId); // Find associated user 7 res.json({ ...post, user }); // Return post with user details 8});
To retrieve a single post, we use the /posts/:id
endpoint. The :id
part of the URL is a route parameter that allows us to capture the specific post ID from the request. We search the posts
array for a post matching the provided ID. If no matching post is found, a 404
status code is returned along with a "Post not found" message. If the post is found, we then search for the user associated with the post using the userId
. Finally, we return the post along with the user details.
Retrieve All Posts with Users:
We create a GET endpoint to retrieve all posts along with their associated users. This is beneficial for showing a list of posts with author details.
JavaScript1// Retrieve all Posts 2app.get('/posts', (req, res) => { 3 const detailedPosts = posts.map(post => { 4 const user = users.find(u => u.id === post.userId); // Find user for each post 5 return { ...post, user }; // Combine post with user details 6 }); 7 res.json(detailedPosts); // Return combined data 8});
For retrieving all posts with their corresponding users, the /posts
endpoint is defined. We map through each post in the posts
array and find the related user using the userId
. We then combine the post data with the user data to create a detailed post object. The array of detailed posts is then returned as the response.
Finally, we start the server to listen for incoming requests. This step puts everything together, making your API live and accessible.
JavaScript1// Start the server 2app.listen(PORT, () => { 3 console.log(`Server running on http://localhost:${PORT}`); 4});
To start the server, we use the app.listen()
method, passing in the port number defined earlier. We also provide a callback function that logs a message indicating the server is running. This is the final step to make your API operational and ready to handle requests.
You've now learned how to set up an Express.js server, create mock data, write endpoints for adding and retrieving data, and start your server. Practice these concepts to reinforce your understanding. Happy coding!