0% found this document useful (0 votes)
3 views35 pages

API Explanations

This document provides a comprehensive introduction to APIs in backend development using JavaScript, particularly with Node.js and Express. It explains the concept of APIs through a restaurant analogy, detailing how clients interact with servers via HTTP methods, endpoints, and JSON data. Additionally, it includes a step-by-step guide to building a simple book management API, covering setup, coding, and testing using tools like Postman and curl.

Uploaded by

victor moses
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)
3 views35 pages

API Explanations

This document provides a comprehensive introduction to APIs in backend development using JavaScript, particularly with Node.js and Express. It explains the concept of APIs through a restaurant analogy, detailing how clients interact with servers via HTTP methods, endpoints, and JSON data. Additionally, it includes a step-by-step guide to building a simple book management API, covering setup, coding, and testing using tools like Postman and curl.

Uploaded by

victor moses
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/ 35

Absolutely!

Let's break down APIs in the backend using JavaScript from the
ground up.

What is an API? (The Restaurant Analogy)

Imagine you go to a restaurant. You don't go into the kitchen and cook your
own food, right? You look at the menu, tell the waiter what you want, and the
waiter brings it to your table.

* You (the customer): This is like the "client" (e.g., your web browser, a
mobile app).

* The Menu: This is like the "API documentation" – it tells you what you can
ask for.

* The Waiter: This is the "API" itself. It takes your request, goes to the
kitchen, gets the food, and brings it back to you.

* The Kitchen: This is the "backend server" where all the work happens (data
storage, logic, etc.).

* The Food: This is the "data" that the API returns.

In programming terms, an API (Application Programming Interface) is a set of


rules and definitions that allow different software applications to
communicate with each other. It defines how software components should
interact.

Why do we need APIs in the Backend?

In a typical web application, you have two main parts:

* Frontend: What the user sees and interacts with (HTML, CSS, JavaScript in
the browser).

* Backend: The "server-side" where data is stored, business logic is handled,


and databases are managed.

The frontend needs to get data from the backend (e.g., a list of products,
user profiles) and send data to the backend (e.g., save a new user, place an
order). APIs are the bridge that enables this communication.

Key Concepts for Backend APIs

Before we dive into JavaScript, let's understand some fundamental concepts:

1. HTTP (Hypertext Transfer Protocol)


This is the standard protocol for communication on the web. When your
browser requests a webpage or data from a server, it uses HTTP.

2. HTTP Methods (Verbs)

These indicate the type of action you want to perform on a resource:

* GET: Retrieve data. (e.g., "Get me all the products.")

* POST: Send new data to the server to create a resource. (e.g., "Create a
new user with this information.")

* PUT: Update an existing resource with new data. (e.g., "Update the details
of product ID 123.")

* DELETE: Remove a resource. (e.g., "Delete product ID 123.")

* PATCH: Partially update an existing resource. (e.g., "Update only the price
of product ID 123.")

3. URLs/Endpoints

An endpoint is a specific URL that represents a unique resource or


functionality on the server. For example:

* /products (to get all products)

* /products/123 (to get a specific product with ID 123)

* /users (to get all users or create a new user)

4. Request and Response

* Request: What the client sends to the server. It includes:

* HTTP Method (GET, POST, etc.)

* URL/Endpoint

* Headers (metadata like content type, authorization tokens)

* Body (data you're sending, especially for POST/PUT)

* Response: What the server sends back to the client. It includes:

* HTTP Status Code (e.g., 200 OK, 404 Not Found, 500 Internal Server
Error)

* Headers

* Body (the data requested, often in JSON format)


5. JSON (JavaScript Object Notation)

JSON is the most common data format for APIs. It's human-readable and easy
for machines to parse. It looks like JavaScript objects:

"id": 1,

"name": "Laptop",

"price": 1200,

"inStock": true

Building a Simple Backend API with JavaScript (Node.js & Express)

To run JavaScript on the backend, we use Node.js. Node.js is a runtime


environment that allows you to execute JavaScript code outside of a web
browser.

For building APIs with Node.js, a popular framework is Express.js. It simplifies


routing, handling requests, and sending responses.

Let's build a very basic API to manage a list of "books."

Step 1: Set up Your Environment

* Install Node.js: If you don't have it, download and install it from the official
Node.js website: https://nodejs.org/

* Create a Project Folder:

mkdir my-book-api

cd my-book-api

* Initialize Node.js Project: This creates a package.json file, which manages


your project's dependencies.

npm init -y

* Install Express.js:
npm install express

Step 2: Create Your API File (app.js)

Create a file named app.js in your my-book-api folder and add the following
code:

// 1. Import the Express library

const express = require('express');

const app = express(); // Create an Express application instance

const port = 3000; // Define the port your server will listen on

// 2. Middleware to parse JSON request bodies

// This is crucial for handling POST and PUT requests where data is sent as
JSON

app.use(express.json());

// 3. Our "database" (for simplicity, we'll use an array in memory)

let books = [

{ id: 1, title: 'The Hobbit', author: 'J.R.R. Tolkien' },

{ id: 2, title: 'Pride and Prejudice', author: 'Jane Austen' },

{ id: 3, title: '1984', author: 'George Orwell' }

];

// 4. Define API Endpoints (Routes)

// GET /books - Get all books

app.get('/books', (req, res) => {

console.log('GET /books request received');


res.json(books); // Send the 'books' array as a JSON response

});

// GET /books/:id - Get a specific book by ID

app.get('/books/:id', (req, res) => {

const bookId = parseInt(req.params.id); // Get the ID from the URL


parameters

console.log(`GET /books/${bookId} request received`);

const book = books.find(b => b.id === bookId); // Find the book in our
array

if (book) {

res.json(book); // If found, send the book as JSON

} else {

res.status(404).json({ message: 'Book not found' }); // If not found,


send 404

});

// POST /books - Add a new book

app.post('/books', (req, res) => {

const newBook = req.body; // The client sends the new book data in the
request body

console.log('POST /books request received:', newBook);

if (!newBook.title || !newBook.author) {

return res.status(400).json({ message: 'Title and author are


required' });
}

// Assign a unique ID (simple increment for demonstration)

const newId = books.length > 0 ? Math.max(...books.map(b => b.id)) +


1 : 1;

newBook.id = newId;

books.push(newBook); // Add the new book to our array

res.status(201).json(newBook); // Send back the created book with 201


Created status

});

// PUT /books/:id - Update an existing book

app.put('/books/:id', (req, res) => {

const bookId = parseInt(req.params.id);

const updatedBookData = req.body;

console.log(`PUT /books/${bookId} request received with data:`,


updatedBookData);

let bookFound = false;

books = books.map(book => {

if (book.id === bookId) {

bookFound = true;

return { ...book, ...updatedBookData }; // Merge existing book with


updated data

return book;

});
if (bookFound) {

res.json({ message: 'Book updated successfully', updatedBook:


books.find(b => b.id === bookId) });

} else {

res.status(404).json({ message: 'Book not found' });

});

// DELETE /books/:id - Delete a book

app.delete('/books/:id', (req, res) => {

const bookId = parseInt(req.params.id);

console.log(`DELETE /books/${bookId} request received`);

const initialLength = books.length;

books = books.filter(book => book.id !== bookId); // Filter out the book to
be deleted

if (books.length < initialLength) {

res.status(204).send(); // 204 No Content for successful deletion

} else {

res.status(404).json({ message: 'Book not found' });

});

// 5. Start the server

app.listen(port, () => {
console.log(`Book API listening at http://localhost:${port}`);

});

Explanation of the Code:

* const express = require('express');: Imports the Express library.

* const app = express();: Creates an Express application instance. This app


object is where you'll configure your routes and middleware.

* const port = 3000;: Defines the port number your server will listen on. You
can choose any available port (e.g., 8080, 5000).

* app.use(express.json());: This is a piece of middleware. Middleware


functions execute in the middle of a request-response cycle. express.json()
specifically tells Express to parse incoming request bodies with JSON
payloads. Without this, req.body would be undefined for POST and PUT
requests.

* let books = [...]: Our "database" for this simple example is just a JavaScript
array. In a real application, you'd connect to a database like MongoDB,
PostgreSQL, MySQL, etc.

* app.get('/books', (req, res) => { ... });:

* app.get() defines a route that responds to GET requests.

* /books is the endpoint.

* (req, res) => { ... } is the route handler function.

* req (request object): Contains information about the incoming HTTP


request (headers, body, parameters, query strings).

* res (response object): Used to send the HTTP response back to the
client.

* res.json(books);: Sends the books array as a JSON response. Express


automatically sets the Content-Type header to application/json.

* app.get('/books/:id', ...):

* /:id is a route parameter. The colon (:) signifies that id is a placeholder for
a dynamic value.
* req.params.id: How you access the value of the route parameter (e.g., if
the URL is /books/1, req.params.id will be "1"). We use parseInt() to convert it
to a number.

* app.post('/books', ...):

* Handles POST requests to create new books.

* req.body: Contains the data sent by the client in the request body (thanks
to app.use(express.json())).

* res.status(201).json(newBook);: Sends a 201 Created status code, which


is appropriate for successful resource creation.

* app.put('/books/:id', ...):

* Handles PUT requests to update existing books.

* It finds the book by ID and then replaces or merges its data.

* app.delete('/books/:id', ...):

* Handles DELETE requests to remove books.

* res.status(204).send();: Sends a 204 No Content status, indicating that


the request was successful but there's no content to return.

* app.listen(port, () => { ... });: This starts the Express server and makes it
listen for incoming requests on the specified port. The callback function runs
once the server is successfully started.

Step 3: Run Your API

Open your terminal, navigate to your my-book-api folder, and run:

node app.js

You should see the message: Book API listening at http://localhost:3000

Step 4: Test Your API (Using a Tool like Postman or curl)

Now that your server is running, you can interact with it.

Option 1: Using curl (command line)

* GET all books:

curl http://localhost:3000/books
Expected output:

[{"id":1,"title":"The Hobbit","author":"J.R.R. Tolkien"},{"id":2,"title":"Pride


and Prejudice","author":"Jane Austen"},
{"id":3,"title":"1984","author":"George Orwell"}]

* GET a specific book (e.g., ID 1):

curl http://localhost:3000/books/1

Expected output:

{"id":1,"title":"The Hobbit","author":"J.R.R. Tolkien"}

* POST a new book:

curl -X POST -H "Content-Type: application/json" -d '{"title": "The Great


Gatsby", "author": "F. Scott Fitzgerald"}' http://localhost:3000/books

Expected output (with a new ID):

{"title":"The Great Gatsby","author":"F. Scott Fitzgerald","id":4}

(If you then GET /books, you'll see the new book.)

* PUT (update) a book:

curl -X PUT -H "Content-Type: application/json" -d '{"title": "The Hobbit


(Updated Edition)"}' http://localhost:3000/books/1

Expected output:

{"message":"Book updated successfully","updatedBook":


{"id":1,"title":"The Hobbit (Updated Edition)","author":"J.R.R. Tolkien"}}
* DELETE a book:

curl -X DELETE http://localhost:3000/books/2

Expected output: (No content, as it's 204)

(If you then GET /books, you'll see "Pride and Prejudice" is gone.)

Option 2: Using Postman (Recommended for beginners)

* Download Postman: https://www.postman.com/downloads/

* Open Postman.

* Click the "+" tab to create a new request.

* For GET requests:

* Select GET from the dropdown.

* Enter http://localhost:3000/books in the URL field.

* Click "Send".

* For POST requests:

* Select POST from the dropdown.

* Enter http://localhost:3000/books in the URL field.

* Go to the "Body" tab, select "raw", and choose "JSON" from the
dropdown.

* Enter your JSON data (e.g., {"title": "New Book", "author": "Someone"}).

* Click "Send".

* Repeat for PUT and DELETE, adjusting the method, URL (with ID), and body
as needed.

What's Next? (Beyond the Basics)

This is just the beginning! A real-world backend API involves much more:

* Databases: Instead of an in-memory array, you'd connect to a persistent


database (e.g., MongoDB, PostgreSQL, MySQL) to store data.
* Database ORMs/Drivers: Libraries that help you interact with databases
more easily (e.g., Mongoose for MongoDB, Sequelize for SQL databases,
Prisma).

* Error Handling: More robust ways to catch and respond to errors.

* Authentication & Authorization: Securing your API so only authorized users


can access certain resources.

* Validation: Ensuring incoming data is in the correct format and meets


requirements.

* Logging: Recording events and errors for debugging and monitoring.

* Deployment: Making your API live on a server (e.g., Heroku, AWS,


DigitalOcean, Vercel).

* Testing: Writing automated tests for your API endpoints.

* Asynchronous Operations: Handling operations that take time (like


database queries) without blocking your server using async/await.

* CORS (Cross-Origin Resource Sharing): Configuring your API to allow


requests from different domains (important when your frontend is on a
different domain than your backend).

Summary: API Flow

* Client (Frontend) makes an HTTP request to the server's API endpoint.

* Request includes: HTTP Method (GET, POST, etc.), URL, Headers, Body (for
POST/PUT).

* Backend Server (Node.js/Express) receives the request.

* Express routes the request to the appropriate route handler based on the
method and URL.

* Route Handler

* Accesses request data (req.params, req.body, req.query).

* Performs necessary logic (e.g., interacts with a database).

* Prepares a response.

* Response is sent back to the client, including: HTTP Status Code, Headers,
Body (often JSON data).
* Client (Frontend) receives the response and uses the data to update the UI
or perform other actions.

I hope this comprehensive explanation helps you understand APIs in the


backend with JavaScript! It's a foundational concept for building any dynamic
web application. Keep practicing, and you'll get the hang of it.

More detailed explanation on API


You got it! Let’s dive into APIs in backend development with JavaScript,
specifically using Node.js, for complete beginners. We’ll go from the very
basics to building a simple, working example.

What is an API? (The Restaurant Analogy, Revisited for Tech)

As we discussed, an API (Application Programming Interface) is like a menu


and a waiter for software.

* Menu (API Definition): It defines what actions you can perform and how to
ask for them. For a software system, this means specifying what data you
can get, what data you can send, and in what format.

* Waiter (API Endpoint): This is the specific address or location you go to


make your request.

* Kitchen (Backend Server): This is where the work gets done – data is
processed, retrieved, or stored.

* Customer (Frontend Application or another Backend): This is the part of


your software that uses the API to interact with another system.

Why do we need APIs in the backend?

Imagine you’re building an e-commerce website. You have:

* A website (frontend): What the user sees in their browser.

* A database: Where all your product information, user accounts, orders,


etc., are stored.

The website can’t directly talk to the database. That would be a security
nightmare and incredibly complex. This is where the backend with its APIs
comes in:
* The backend acts as a secure intermediary between your frontend and
your database.

* It exposes APIs that the frontend can call to, for example:

* Get a list of products.

* Add a product to the cart.

* Process an order.

* Create a new user account.

The backend handles the logic, talks to the database, performs calculations,
and then sends back the requested data (or a confirmation of an action) to
the frontend.

What is JavaScript in the Backend (Node.js)?

Traditionally, JavaScript was only used for frontend development (making


websites interactive in the browser). However, with the advent of Node.js,
JavaScript can now be run on the server-side!

* Node.js: It’s a JavaScript runtime environment that allows you to execute


JavaScript code outside of a web browser. This means you can use JavaScript
to build entire backend applications, including APIs.

* Why Node.js for APIs?

* Same language for frontend and backend: If you know JavaScript for the
frontend, you can use it for the backend too, reducing the learning curve.

* Asynchronous and Event-Driven: Node.js is excellent for handling many


concurrent requests, making it efficient for API servers.

* Large Ecosystem: npm (Node Package Manager) has a vast collection of


libraries and frameworks that speed up development.

Let’s Build a Simple API with Node.js and Express.js!

We’ll create a very basic API that manages a list of “books.” You’ll be able to:

* Get all books.

* Get a specific book by its ID.

* Add a new book.

Before we start, you’ll need:


* Node.js installed on your computer: If you don’t have it, go to nodejs.org
and download the recommended LTS (Long Term Support) version.

* A text editor: VS Code is highly recommended (code.visualstudio.com).

* A terminal or command prompt: To run Node.js commands.

* Postman or a similar API testing tool (optional but very helpful): This allows
you to send requests to your API and see the responses easily. You can
download it from postman.com/downloads.

Step 1: Project Setup

* Create a new folder for your project. Let’s call it my-book-api.

* Open your terminal and navigate into that folder:

Cd my-book-api

 Initialize a Node.js project: This creates a package.json file, which


manages your project’s dependencies and scripts.

Npm init -y

The -y flag answers “yes” to all the default questions, making it quicker.

 Install Express.js: Express is a popular web framework for Node.js that


simplifies building web applications and APIs.

Npm install express

Now, your package.json file should look something like this (the version
numbers might differ):

“name”: “my-book-api”,

“version”: “1.0.0”,

“description”: “”,

“main”: “index.js”,

“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1”

},

“keywords”: [],

“author”: “”,

“license”: “ISC”,

“dependencies”: {

“express”: “^4.19.2”

Step 2: Create Your API Server (index.js)

Create a new file named index.js in your my-book-api folder. This will be the
main file for our backend server.

// index.js

// 1. Import the Express library

Const express = require(‘express’);

// 2. Create an Express application instance

Const app = express();

// 3. Define the port our server will listen on

Const PORT = 3000;

// 4. Middleware to parse JSON request bodies

// When a frontend sends data (e.g., a new book), it’s often in JSON format.
// This line tells Express to automatically parse that JSON into a JavaScript
object

// that we can easily use in our routes.

App.use(express.json());

// 5. Our “Database” (for this simple example, it’s just an array in memory)

// In a real application, this would be a proper database like MongoDB,


PostgreSQL, etc.

Let books = [

{ id: 1, title: ‘The Hitchhiker\’s Guide to the Galaxy’, author: ‘Douglas


Adams’ },

{ id: 2, title: ‘1984’, author: ‘George Orwell’ },

{ id: 3, title: ‘Pride and Prejudice’, author: ‘Jane Austen’ }

];

// --- API Endpoints (Routes) ---

// 6. GET /books – Get all books

// This defines a route that responds to HTTP GET requests to the ‘/books’
path.

// ‘req’ (request) contains information about the incoming request.

// ‘res’ (response) is used to send back a response to the client.

App.get(‘/books’, (req, res) => {

Console.log(‘Received GET request for /books’);

// Send back the entire books array as JSON

Res.json(books);

});
// 7. GET /books/:id – Get a single book by ID

// The ‘:id’ is a route parameter. It means whatever comes after /books/ will
be captured

// and made available in req.params.id.

App.get(‘/books/:id’, (req, res) => {

Const bookId = parseInt(req.params.id); // Convert the ID from string to


number

Console.log(`Received GET request for book with ID: ${bookId}`);

// Find the book in our array

Const book = books.find(b => b.id === bookId);

If (book) {

// If book is found, send it back as JSON

Res.json(book);

} else {

// If not found, send a 404 Not Found status with a message

Res.status(404).json({ message: ‘Book not found’ });

});

// 8. POST /books – Add a new book

// This route handles HTTP POST requests. POST requests are typically used
to create new resources.

App.post(‘/books’, (req, res) => {

// The new book data is sent in the request body (thanks to


app.use(express.json()))

Const newBook = req.body;


Console.log(‘Received POST request to add a new book:’, newBook);

// Basic validation: Check if title and author exist

If (!newBook.title || !newBook.author) {

// Send a 400 Bad Request status if data is missing

Return res.status(400).json({ message: ‘Title and author are


required’ });

// Generate a unique ID for the new book

// (In a real app, this would be handled by the database)

Const newId = books.length > 0 ? Math.max(…books.map(b => b.id)) + 1 :


1;

newBook.id = newId;

// Add the new book to our array

Books.push(newBook);

// Send back the newly created book with a 201 Created status

Res.status(201).json(newBook);

});

// 9. Start the server

App.listen(PORT, () => {

Console.log(`Server is running on http://localhost:${PORT}`);

Console.log(‘API Endpoints:’);
Console.log(`- GET http://localhost:${PORT}/books`);

Console.log(`- GET http://localhost:${PORT}/books/:id`);

Console.log(`- POST http://localhost:${PORT}/books`);

});

Step 3: Run Your API Server

* Open your terminal and navigate to your my-book-api folder.

* Run the server:

Node index.js

You should see output like:

Server is running on http://localhost:3000

API Endpoints:

- GET http://localhost:3000/books

- GET http://localhost:3000/books/:id

- POST http://localhost:3000/books

Your API server is now up and running! It’s listening for requests on port
3000 of your local machine.

Step 4: Test Your API

Now, let’s use a web browser or Postman to interact with our API.

A. Using a Web Browser (for GET requests only):

* Get all books: Open your browser and go to http://localhost:3000/books

You should see the JSON response:

{ “id”: 1, “title”: “The Hitchhiker’s Guide to the Galaxy”, “author”: “Douglas


Adams” },
{ “id”: 2, “title”: “1984”, “author”: “George Orwell” },

{ “id”: 3, “title”: “Pride and Prejudice”, “author”: “Jane Austen” }

 Get a specific book: Go to http://localhost:3000/books/2

You should see:

{ “id”: 2, “title”: “1984”, “author”: “George Orwell” }

If you try http://localhost:3000/books/99, you’ll get:

{ “message”: “Book not found” }

B. Using Postman (Recommended for all requests, especially POST):

* Open Postman.

* Click the “+” tab to create a new request.

* Test GET All Books:

* Set the HTTP method to GET.

* Enter the URL: http://localhost:3000/books

* Click Send.

* You’ll see the JSON response in the “Body” section.

* Test GET Single Book:

* Set the HTTP method to GET.

* Enter the URL: http://localhost:3000/books/1

* Click Send.

* You’ll see the JSON response for “The Hitchhiker’s Guide to the Galaxy”.

* Test POST Add New Book:

* Set the HTTP method to POST.

* Enter the URL: http://localhost:3000/books


* Go to the Body tab below the URL.

* Select raw and then choose JSON from the dropdown.

* In the text area, paste the following JSON:

“title”: “The Great Gatsby”,

“author”: “F. Scott Fitzgerald”

* Click Send.

* You should get a 201 Created status and the newly added book, including
its generated id:

“title”: “The Great Gatsby”,

“author”: “F. Scott Fitzgerald”,

“id”: 4

 Now, if you send another GET request to http://localhost:3000/books,


you’ll see “The Great Gatsby” in the list!

Understanding the Code (Detailed Breakdown)

Let’s revisit the index.js file and break down each part:

Const express = require(‘express’); // 1. Import Express

Const app = express(); // 2. Create Express app

Const PORT = 3000; // 3. Define port

// 4. Middleware: app.use(express.json());

// This is crucial! When your frontend sends data (especially with POST or
PUT requests),
// it’s typically in JSON format. This line tells Express to automatically parse

// that JSON string from the request body into a JavaScript object. Without
this,

// req.body would be undefined. This is a form of ‘middleware’ – code that


runs

// before your main route handler.

// 5. Our “Database”: let books = […];

// For simplicity, we’re using a simple JavaScript array to store our books.

// This data is *volatile* - it disappears when you stop and restart your server.

// In a real-world application, you would connect to a persistent database like:

// - MongoDB (NoSQL)

// - PostgreSQL (SQL)

// - MySQL (SQL)

// - SQLite (SQL, good for small projects)

// Connecting to these would involve installing specific database driver


libraries

// (e.g., ‘mongoose’ for MongoDB, ‘pg’ for PostgreSQL) and writing code to

// interact with them.

// --- API Endpoints (Routes) ---

// 6. GET /books – Get all books

App.get(‘/books’, (req, res) => {

// `app.get()`: This method handles HTTP GET requests.

// `/books`: This is the *path* or *endpoint*. When a request comes to this


URL,

// this specific function (the “route handler”) will be executed.


// `(req, res) => { … }`: This is the route handler function.

// - `req` (Request object): Contains all information about the incoming


HTTP request.

// This includes headers, URL parameters, query strings, and the request
body (if any).

// - `res` (Response object): Used to send back the HTTP response to the
client.

// You’ll use methods like `res.send()`, `res.json()`, `res.status()`, etc.

Console.log(‘Received GET request for /books’);

Res.json(books);

// `res.json(books)`: This method automatically sets the Content-Type


header to

// `application/json` and sends the JavaScript `books` array as a JSON


string to the client.

// This is the most common way to return data from an API.

});

// 7. GET /books/:id – Get a single book by ID

App.get(‘/books/:id’, (req, res) => {

// `/:id`: This is a *route parameter*. The `id` part is a placeholder.

// Whatever value is in that position in the URL (e.g., `5` in `/books/5`)

// will be available in `req.params.id`.

Const bookId = parseInt(req.params.id);

// `parseInt()`: Route parameters are always strings by default. We convert


`id` to an integer

// because our book IDs in the array are numbers.

Console.log(`Received GET request for book with ID: ${bookId}`);


Const book = books.find(b => b.id === bookId);

// `Array.prototype.find()`: A JavaScript array method that returns the first


element

// in the array that satisfies the provided testing function.

If (book) {

Res.json(book); // If found, send the book data.

} else {

Res.status(404).json({ message: ‘Book not found’ });

// `res.status(404)`: Sets the HTTP status code of the response to 404


(Not Found).

// HTTP status codes are important for clients to understand


the result of their request.

// Common codes:

// - 200 OK: Request succeeded.

// - 201 Created: New resource created (often used with


POST).

// - 400 Bad Request: Client sent invalid data.

// - 401 Unauthorized: Client needs to authenticate.

// - 403 Forbidden: Client is authenticated but doesn’t have


permission.

// - 404 Not Found: Resource not found.

// - 500 Internal Server Error: Something went wrong on the


server.

});

// 8. POST /books – Add a new book

App.post(‘/books’, (req, res) => {


// `app.post()`: Handles HTTP POST requests. Used for creating new
resources.

Const newBook = req.body;

// `req.body`: This is where the data sent by the client (e.g., the new book’s
title and author)

// is located. Remember, `app.use(express.json())` parsed it for us.

Console.log(‘Received POST request to add a new book:’, newBook);

If (!newBook.title || !newBook.author) {

Return res.status(400).json({ message: ‘Title and author are


required’ });

// `return`: It’s important to `return` after sending a response to prevent


further code execution

// in the same route handler, which could lead to errors or sending


multiple responses.

Const newId = books.length > 0 ? Math.max(…books.map(b => b.id)) + 1 :


1;

// This is a simple way to generate a unique ID.

// It finds the maximum existing ID and adds 1. If no books, starts at 1.

newBook.id = newId;

books.push(newBook);

// Add the new book object to our in-memory array.

Res.status(201).json(newBook);

// Send back the newly created book object with a 201 status code.

});
// 9. Start the server

App.listen(PORT, () => {

// `app.listen()`: This method starts the Express server and makes it listen

// for incoming HTTP requests on the specified `PORT`.

// The callback function `() => { … }` runs once the server has successfully
started.

Console.log(`Server is running on http://localhost:${PORT}`);

});

Next Steps and Important Concepts

This is just the tip of the iceberg! Here are crucial concepts you’ll encounter
as you progress:

* HTTP Methods (Verbs):

* GET: Retrieve data (e.g., get a list of products, get a specific user).

* POST: Create new data (e.g., create a new user, submit an order).

* PUT: Update existing data completely (replace the entire resource).

* PATCH: Update existing data partially (modify specific fields).

* DELETE: Remove data (e.g., delete a product).

* These are standard conventions for how APIs should behave.

* Databases: Our current “database” is just an array, which means data is


lost when the server restarts. To make your data persistent, you’ll need to
learn about:

* SQL Databases (Relational): PostgreSQL, MySQL, SQLite. Data is stored in


structured tables with relationships.

* NoSQL Databases (Non-relational): MongoDB, Cassandra, Redis. Offer


more flexible data models.
* You’ll use ODMs (Object Document Mappers) like Mongoose (for
MongoDB) or ORMs (Object Relational Mappers) like Sequelize (for SQL) to
interact with databases from Node.js in an object-oriented way.

* Error Handling: Robust APIs have good error handling to provide


meaningful messages to clients when something goes wrong (e.g., invalid
input, resource not found, server errors).

* Authentication and Authorization:

* Authentication: Verifying who the user is (e.g., username/password, JWTs


– JSON Web Tokens).

* Authorization: Determining what an authenticated user is allowed to do.

* You’ll use middleware like Passport.js or implement JWT-based


authentication.

* Validation: Ensuring that the data received from the client is valid and
meets your requirements before processing it (e.g., checking if an email
address is in the correct format). Libraries like joi or express-validator are
common.

* Middleware: Functions that have access to the request and response


objects and can perform tasks before the route handler is executed.
express.json() is an example. Other common middleware includes:

* Logging: To log incoming requests.

* CORS (Cross-Origin Resource Sharing): To allow your frontend (on a


different domain) to make requests to your backend.

* Authentication middleware: To protect routes.

* Deployment: Getting your API server online so others can access it. This
involves services like Heroku, Vercel, AWS, Google Cloud, DigitalOcean, etc.

* Testing: Writing automated tests for your API endpoints to ensure they
work as expected.

You’ve built your first basic API! This is a fantastic start. Keep exploring, keep
building, and don’t be afraid to experiment. Happy coding!
Difference between GET & POST
requests in an API

It’s crucial to differentiate between GET and POST requests when designing
your backend API because it dictates how clients interact with your server
and ensures your application is robust, secure, and semantically correct.

Here's the breakdown:

When to Use GET Requests

Use GET requests when you want to retrieve (read) data from the server
without causing any side effects (i.e., without changing the server’s state).

Characteristics of GET:

* Idempotent: Making the same GET request multiple times will have the
same effect as making it once (it will return the same data).

* Safe: It does not modify data on the server.

* Data is sent in the URL as query parameters.

* Can be cached by browsers and proxies.

* Can be bookmarked.

Examples of GET requests:

* Fetching a list of all products.

* Retrieving the details of a single user by their ID.

* Searching for articles based on keywords.

* Getting a list of available categories.

* Checking the status of an order.

When to Use POST Requests

Use POST requests when you want to send data to the server to create a new
resource or to perform an operation that has side effects (i.e., changes the
server’s state).

Characteristics of POST:
* Not Idempotent: Making the same POST request multiple times will
typically create multiple new resources.

* Not Safe: It modifies data on the server.

* Data is sent in the request body.

* Generally not cached.

* Should not be bookmarked.

Examples of POST requests:

* Creating a new user account.

* Submitting a contact form.

* Adding a new product to a database.

* Placing an order.

* Uploading an image.

* Logging a user in (though sometimes POST is used for login, it’s generally
considered best practice for changing state like user session).

Project Example: A Simple Blog API

Let’s design a simple backend API for a blog. This project will clearly
demonstrate when to use GET and POST.

Core Entities:

* Posts: Blog articles.

* Comments: User comments on posts.

API Endpoints:

* Retrieving Posts (GET):

* Endpoint: /api/posts

* Method: GET

* Purpose: To get a list of all blog posts.

* Expected Response: An array of post objects.

* Example Usage: A blog’s homepage fetching all articles to display.

* Endpoint: /api/posts/:id (where :id is a placeholder for a specific post’s ID)


* Method: GET

* Purpose: To retrieve the details of a single blog post.

* Expected Response: A single post object.

* Example Usage: When a user clicks on an article title to read its full
content.

* Endpoint: /api/posts/:id/comments

* Method: GET

* Purpose: To retrieve all comments associated with a specific post.

* Expected Response: An array of comment objects.

* Example Usage: Displaying comments below a blog post.

* Creating a New Post (POST):

* Endpoint: /api/posts

* Method: POST

* Purpose: To add a new blog post to the database.

* Expected Request Body: A JSON object containing the post’s title,


content, author, etc.

“title”: “My First Blog Post”,

“content”: “This is the amazing content of my first post.”,

“author”: “John Doe”

* Expected Response: The newly created post object (often with an


assigned ID) and a success status.

* Example Usage: A blog administrator using a dashboard to publish a new


article. If they hit “submit” multiple times, they would accidentally create
multiple identical posts.

* Adding a Comment to a Post (POST):


* Endpoint: /api/posts/:id/comments

* Method: POST

* Purpose: To add a new comment to a specific blog post.

* Expected Request Body: A JSON object containing the author,


comment_text, etc.

“author”: “Jane Smith”,

“comment_text”: “Great article!”

* Expected Response: The newly created comment object and a success


status.

* Example Usage: A reader submitting a comment on a blog post.

Why this differentiation is correct:

* GET /api/posts and /api/posts/:id are perfect for retrieval. They don’t
change anything on the server. You can refresh the page, share the URL, or
bookmark it, and the data remains consistent without unintended side
effects.

* POST /api/posts is for creating a new resource. Each time you send a POST
request with new post data, you intend to add a new record.

* POST /api/posts/:id/comments is also for creating a new resource (a


comment) associated with an existing post.

This blog API example provides a clear and practical illustration of how GET
and POST requests are used for their distinct purposes in a real-world
backend project.

More explanation on when to use a POST


request
On an API backend, you should primarily use a POST request for operations
that involve sending data to the server to create a new resource or to
perform an action that has side effects (i.e., changes the server’s state).

Here are the specific methods or scenarios that typically require a POST
request:

* Creating New Resources:

* This is the most common and fundamental use case for POST. When a
client wants to add a new entity to your database or system, a POST request
is used.

* Examples:

* /users: Creating a new user account.

* /products: Adding a new product to an e-commerce catalog.

* /orders: Placing a new customer order.

* /posts: Publishing a new blog post.

* /comments: Adding a new comment to an existing post.

* Submitting Form Data:

* Whenever a user fills out a web form (e.g., registration, contact, survey)
and submits it, the data is typically sent to the server via a POST request.
This is because form submissions usually lead to the creation or modification
of data on the server.

* Examples:

* A “Contact Us” form submission.

* A “Sign Up” form for a new account.

* A “Checkout” form in an e-commerce application.

* File Uploads:

* When a client needs to send a file (image, document, video, etc.) to the
server, a POST request is used. The file data is sent in the request body,
often using multipart/form-data encoding.

* Examples:

* Uploading a profile picture.


* Attaching a document to an email.

* Uploading a product image.

* Performing Non-Idempotent Operations (Operations with Side Effects):

* POST requests are used for actions that are not idempotent, meaning
that performing the same request multiple times will have different (and
often undesirable) effects. This usually implies a change in state on the
server.

* Examples:

* Processing a payment: Sending a payment request multiple times via


GET could lead to multiple charges. POST ensures this operation is handled
as a unique transaction.

* Sending an email: If you use POST to send an email, repeating the


request sends another email.

* Logging in/out: While often a GET for logout, login often involves POST
to send credentials securely and create a session.

* Batch operations: If you’re sending a list of items to be processed in a


specific way that changes state.

* When Data is Sensitive or Large:

* While technically not a strict rule about method requiring POST, it’s a
best practice to use POST when sending sensitive data (like passwords,
credit card numbers) or very large amounts of data.

* Security: Data in a POST request’s body is not exposed in the URL,


making it less susceptible to being logged in browser history, server logs, or
proxy caches.

* Size Limits: URLs have practical length limits (though not strictly defined
by HTTP, browsers and servers impose them). POST requests have no such
practical limits on the body size.

Important Distinction (and potential confusion):

While POST is primarily for creating resources, you might sometimes see it
used for complex search queries or “action-based” endpoints where the
query parameters for a GET request would be too long, complex, or sensitive.
In these cases, the semantics might lean towards “retrieving” data, but the
practicalities (data size, complexity, or sensitivity) dictate using POST to put
the query payload in the request body. However, strictly speaking, RESTful
principles would encourage using GET for retrieval if possible.

In essence, if your API call is going to alter the state of the server or create
something new, a POST request is almost always the correct HTTP method to
use.

You might also like