In our previous articles, we've laid the foundation of NodeJS, exploring its core concepts, including how NodeJS works, building servers, managing URLs, and HTTP methods, and utilizing the power of the Express framework. Now, we’ll take a step further by diving into REST APIs, middleware, and HTTP headers, essential components for building efficient and scalable backend applications.
Link to the previous articles:
- Getting Started with NodeJS
- Deepening NodeJS Knowledge: URLs, HTTP Methods, Express Framework, and Versioning
Continuing our deep dive into NodeJS, let's explore some more advanced and crucial concepts that are essential for building robust backend applications.
REST APIs: Understanding and Implementing
What is a REST API?
REST (Representational State Transfer) is an architectural style for designing networked applications. It uses a stateless, client-server, cacheable communication protocol — typically HTTP.
REST APIs are widely used to allow different software systems to communicate over the web. They provide a standardized way to interact with web services.
Types of REST API Requests
-
GET
: Retrieve data from the server. -
POST
: Send data to the server to create a resource. -
PUT
: Update an existing resource on the server. -
DELETE
: Remove a resource from the server. -
PATCH
: Partially update a resource.
Why REST APIs are Needed?
=Before REST, APIs were often tightly coupled to specific clients, making them inflexible and difficult to scale or modify.
REST provides a flexible, scalable way to interact with resources. It allows developers to build APIs that can be consumed by any client that understands HTTP.
Example of a REST API in NodeJS Using Express
Installation:
npm install express
Code:
const express = require('express');
const app = express();
app.use(express.json()); // Middleware to parse JSON bodies
let users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
];
// GET: Retrieve all users
app.get('/api/users', (req, res) => {
res.status(200).json(users);
});
// POST: Create a new user
app.post('/api/users', (req, res) => {
const newUser = { id: users.length + 1, name: req.body.name };
users.push(newUser);
res.status(201).json(newUser);
});
// PUT: Update an existing user
app.put('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) return res.status(404).send('User not found');
user.name = req.body.name;
res.status(200).json(user);
});
// DELETE: Remove a user
app.delete('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) return res.status(404).send('User not found');
const index = users.indexOf(user);
users.splice(index, 1);
res.status(200).json(user);
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
Output:
-
GET:
http://localhost:3000/api/users
returns the list of users. - POST: Sends a new user object, which is added to the list.
- PUT: Updates an existing user.
- DELETE: Removes a user from the list.
Use Case: Building a Simple User Management API
Imagine building a user management system for an application where you need to perform CRUD (Create, Read, Update, Delete) operations. REST APIs are perfect for this, allowing the front end to interact with the backend seamlessly.
Middleware in NodeJS
What is Middleware?
Middleware functions in NodeJS are functions that have access to the request object (req
), the response object (res
), and the next middleware function in the application's request-response cycle.
Middleware can execute any code, make changes to the request and response objects, end the request-response cycle, and call the next middleware function.
Express Middleware
Express middleware functions are used to process requests and responses in an Express application. They can be used to add logging, authentication, parsing, and error handling.
Commonly Used Middleware
-
express.json()
: Parses incoming JSON requests and puts the parsed data inreq.body
. -
express.urlencoded()
: Parses incoming requests with URL-encoded payloads. -
morgan
: A logging middleware. -
cors
: A middleware for enabling Cross-Origin Resource Sharing. -
helmet
: Helps secure Express apps by setting various HTTP headers.
Installation:
npm install morgan cors helmet
How Middleware Functions Work Together?
- Middleware functions are executed in the order they are defined in the app.
- If a middleware function doesn’t end the request-response cycle, it must call
next()
to pass control to the next middleware function.
Example:
const express = require('express');
const morgan = require('morgan');
const cors = require('cors');
const helmet = require('helmet');
const app = express();
app.use(helmet()); // Security middleware
app.use(morgan('combined')); // Logging middleware
app.use(cors()); // Enable CORS
app.use(express.json()); // Parse JSON bodies
// Custom middleware
app.use((req, res, next) => {
console.log('Custom middleware executed');
next(); // Pass control to the next middleware
});
// Route handler
app.get('/', (req, res) => {
res.send('Hello, Middleware!');
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
Output:
- Logs request details (via
morgan
), secures headers (viahelmet
), and enables CORS.
Use Case: Authentication Middleware
You need to ensure that only authenticated users can access certain routes. You can create a custom authentication middleware that checks for a valid token in the request headers before allowing access to the protected routes.
HTTP Headers and Status Codes in API Development
What are HTTP Headers?
HTTP headers are key-value pairs sent between the client and server in an HTTP request or response. They provide essential information about the request or response.
-
Common HTTP Headers:
-
Content-Type
: Specifies the media type of the resource (e.g.,application/json
). -
Authorization
: Contains credentials for authenticating the client. -
Cache-Control
: Directives for caching mechanisms. -
Set-Cookie
: Used to send cookies from the server to the client.
-
HTTP Status Codes
Status codes are issued by a server in response to a client's request. They indicate the result of the request.
-
Common Status Codes:
-
200 OK
: The request was successful. -
201 Created
: A resource was successfully created. -
400 Bad Request
: The server could not understand the request due to invalid syntax. -
401 Unauthorized
: The client must authenticate itself to get the requested response. -
403 Forbidden
: The client does not have access rights to the content. -
404 Not Found
: The server can not find the requested resource. -
500 Internal Server Error
: The server encountered a situation it doesn't know how to handle.
-
Using HTTP Headers in NodeJS
HTTP headers are crucial for managing communication between the client and server, including security, data format, and more.
Example:
const express = require('express');
const app = express();
app.get('/api/data', (req, res) => {
res.setHeader('Content-Type', 'application/json');
res.setHeader('Custom-Header', 'MyValue');
res.status(200).json({ message: 'Data retrieved successfully' });
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
Output:
- The response will include the
Content-Type
asapplication/json
and a custom headerCustom-Header
.
Use Case: Setting CORS Headers
When building a REST API that will be consumed by a web application hosted on a different domain, you need to enable CORS by setting the appropriate headers.
Example:
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
next();
});