[go: up one dir, main page]

0% found this document useful (0 votes)
4 views13 pages

Web II Working With Restful Apis Lesson014

The document explains the concept of RESTful APIs in Express, highlighting their principles such as resource-based URLs, HTTP methods for CRUD operations, and statelessness. It details how Express.js facilitates the creation of these APIs through routing, middleware integration, and response handling. Additionally, it provides code examples for implementing GET, POST, PUT, PATCH, and DELETE operations for user management.

Uploaded by

BRIAN MUTURI
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views13 pages

Web II Working With Restful Apis Lesson014

The document explains the concept of RESTful APIs in Express, highlighting their principles such as resource-based URLs, HTTP methods for CRUD operations, and statelessness. It details how Express.js facilitates the creation of these APIs through routing, middleware integration, and response handling. Additionally, it provides code examples for implementing GET, POST, PUT, PATCH, and DELETE operations for user management.

Uploaded by

BRIAN MUTURI
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 13

The concept of RESTful APIs in Express.

RESTful APIs are a popular way of creating web applications that exchange data
over the internet in a standardized manner. These APIs follow specific principles
such as using resource-based URLs and HTTP methods to perform various
operations like creating, reading, updating, and deleting data. Express js is a
powerful framework that allows developers to easily create routes, handle requests,
and send responses, making it a versatile choice for building APIs that are robust
and scalable.
Understanding the concept of RESTful APIs in Express JS:
 REST Architecture: REST, which stands for Representational State
Transfer, is an architectural style for designing networked applications.
 Resource-Based: RESTful APIs in ExpressJS are designed around
resources, which are identified by unique URLs. These resources represent
the entities (e.g., users, products, articles) that the API manipulates.
 HTTP Methods: RESTful APIs use standard HTTP methods to
perform CRUD (Create, Read, Update, Delete) operations on resources:
o GET: Retrieves data from a resource.
o POST: Creates a new resource.
o PUT: Updates an existing resource.
o DELETE: Deletes a resource.
 Statelessness: RESTful APIs are stateless, meaning that each request from a
client contains all the information needed to process the request. Servers do
not maintain a session state between requests.
 Uniform Interface: RESTful APIs have a uniform interface, which
simplifies communication between clients and servers. This interface
typically involves the use of standard HTTP methods, resource identifiers
(URLs), and representations (e.g., JSON, XML).
 ExpressJS and Routing: In ExpressJS, you define routes to handle
incoming requests for specific resources and HTTP methods. Each route
specifies a callback function to process the request and send an appropriate
response.
 Middleware Integration: ExpressJS middleware can be used to handle
tasks such as request validation, authentication, and response formatting,
enhancing the functionality and security of RESTful APIs.
 Response Codes: RESTful APIs use standard HTTP status codes to indicate
the success or failure of a request. Common status codes include 200 (OK),
201 (Created), 400 (Bad Request), 404 (Not Found), and 500 (Internal
Server Error).

Let’s look at how we can perform CRUD operations:


GET: Retrieves data from a resource.
const getUsers = (req, res) => {
// Access query parameters
const { name, email } = req.query;

let filteredUsers = [...users];

// Filter by name if provided


if (name) {
filteredUsers = filteredUsers.filter(user =>
user.name.toLowerCase().includes(name.toLowerCase())
);
}

// Filter by email if provided


if (email) {
filteredUsers = filteredUsers.filter(user =>
user.email.toLowerCase().includes(email.toLowerCase())
);
}

res.json(filteredUsers);
};

POST: Creates a new resource.


const createUser = (req, res) => {
const { name, email } = req.body;

if (!name || !email) {
return res.status(400).json({
error: 'Both name and email are required'
});
}

// Generate new ID (max existing ID + 1)


const newId = users.length > 0 ? Math.max(...users.map(u => u.id)) + 1 : 1;
const newUser = { id: newId, name, email };

users.push(newUser); // Add to the shared array


res.status(201).json(newUser);
};

PUT: Updates an existing resource (full update)


const updateUser = (req, res) => {
const id = parseInt(req.params.id);
const { name, email } = req.body;

if (!name || !email) {
return res.status(400).json({
error: 'Both name and email are required for full update'
});
}

const userIndex = users.findIndex(u => u.id === id);

if (userIndex === -1) {


return res.status(404).json({ error: 'User not found' });
}

users[userIndex] = { id, name, email };


res.json(users[userIndex]);
};
PATCH – used for partial update
const patchUser = (req, res) => {
const id = parseInt(req.params.id);
const { name, email } = req.body;

if (!name && !email) {


return res.status(400).json({
error: 'At least one field (name or email) is required for update'
});
}

const userIndex = users.findIndex(u => u.id === id);

if (userIndex === -1) {


return res.status(404).json({ error: 'User not found' });
}

// Update only provided fields


const userToUpdate = users[userIndex];
if (name) userToUpdate.name = name;
if (email) userToUpdate.email = email;

res.json(userToUpdate);
};
DELETE: Deletes a resource.
const deleteUser = (req, res) => {
const id = parseInt(req.params.id);
const userIndex = users.findIndex(u => u.id === id);

if (userIndex === -1) {


return res.status(404).json({ error: 'User not found' });
}

const [deletedUser] = users.splice(userIndex, 1);


res.json({ message: 'User deleted successfully', deletedUser });
};
HERE IS A FULL SAMPLE OF THE CODES
routes/users.js
const express = require('express');
const router = express.Router();
const usersController = require('../controllers/users');

router.get('/', usersController.getUsers);

router.post('/', usersController.createUser);

router.get('/:id', usersController.getUserById);
router.put('/:id', usersController.updateUser);

// PATCH (Partial update)


router.patch('/:id', usersController.patchUser);

router.delete('/:id', usersController.deleteUser);

module.exports = router;

server.js
const express = require('express');
const app = express();

const userRoutes = require('./routes/users');

app.use(express.json());

app.use('/api/users', userRoutes);

// Error handling middleware


app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something went wrong!' });
});

const PORT = 3000;


app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});

controllers/users.js
let users = [
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
];

// GET /api/users
const getUsers = (req, res) => {
// Access query parameters
const { name, email } = req.query;

let filteredUsers = [...users];

// Filter by name if provided


if (name) {
filteredUsers = filteredUsers.filter(user =>
user.name.toLowerCase().includes(name.toLowerCase())
);
}

// Filter by email if provided


if (email) {
filteredUsers = filteredUsers.filter(user =>
user.email.toLowerCase().includes(email.toLowerCase())
);
}

res.json(filteredUsers);
};

// POST /api/users
const createUser = (req, res) => {
const { name, email } = req.body;

if (!name || !email) {
return res.status(400).json({
error: 'Both name and email are required'
});
}

// Generate new ID (max existing ID + 1)


const newId = users.length > 0 ? Math.max(...users.map(u => u.id)) + 1 : 1;
const newUser = { id: newId, name, email };

users.push(newUser); // Add to the shared array


res.status(201).json(newUser);
};

// GET /api/users/:id
const getUserById = (req, res) => {
const id = parseInt(req.params.id);
const user = users.find(u => u.id === id);

if (!user) {
return res.status(404).json({ error: 'User not found' });
}

res.json(user);
};

// PUT /api/users/:id (Full update)


const updateUser = (req, res) => {
const id = parseInt(req.params.id);
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({
error: 'Both name and email are required for full update'
});
}

const userIndex = users.findIndex(u => u.id === id);

if (userIndex === -1) {


return res.status(404).json({ error: 'User not found' });
}

users[userIndex] = { id, name, email };


res.json(users[userIndex]);
};

// PATCH /api/users/:id (Partial update)


const patchUser = (req, res) => {
const id = parseInt(req.params.id);
const { name, email } = req.body;

if (!name && !email) {


return res.status(400).json({
error: 'At least one field (name or email) is required for update'
});
}

const userIndex = users.findIndex(u => u.id === id);

if (userIndex === -1) {


return res.status(404).json({ error: 'User not found' });
}

// Update only provided fields


const userToUpdate = users[userIndex];
if (name) userToUpdate.name = name;
if (email) userToUpdate.email = email;

res.json(userToUpdate);
};

// DELETE /api/users/:id
const deleteUser = (req, res) => {
const id = parseInt(req.params.id);
const userIndex = users.findIndex(u => u.id === id);

if (userIndex === -1) {


return res.status(404).json({ error: 'User not found' });
}

const [deletedUser] = users.splice(userIndex, 1);


res.json({ message: 'User deleted successfully', deletedUser });
};

module.exports = {
getUsers,
createUser,
getUserById,
updateUser,
patchUser,
deleteUser
};

You might also like