OdinSchool OdinSchool

HTTP Server in Nodejs

Lesson 4 – HTTP Server

 

Welcome to the culmination of your Node.js journey! In this lesson, we dive into the realm of building HTTP servers, a fundamental skill in Node.js development. From handling requests and responses to creating a RESTful API with Express.js, we'll explore the intricacies of server-side development.

 

 4.1 Creating an HTTP Server with Node.js

 

 4.1.1 Handling Requests and Responses

 

Understanding Request and Response Objects:

- In Node.js, HTTP servers interact with request and response objects.

- The request object contains information about the incoming request, while the response object facilitates the server's response.

 

Example of Request and Response Handling:

```javascript

const http = require('http');

 

const server = http.createServer((req, res) => {

    // Handling a basic GET request

    if (req.method === 'GET' && req.url === '/hello') {

        res.writeHead(200, { 'Content-Type': 'text/plain' });

        res.end('Hello, Node.js!');

    } else {

        res.writeHead(404, { 'Content-Type': 'text/plain' });

        res.end('Not Found');

    }

});

 

const PORT = 3000;

server.listen(PORT, () => {

    console.log(`Server running at http://localhost:${PORT}/`);

});

```

 

Key Takeaways:

- `req.method` and `req.url` provide information about the incoming request.

- `res.writeHead` sets the status code and response headers.

- `res.end` sends the response to the client.

 

 4.1.2 Middleware in Express.js

 

Introduction to Middleware:

- Middleware functions in Express.js have access to the request and response objects.

- They can modify these objects, execute code, and terminate the request-response cycle.

 

Implementing Custom Middleware:

- Middleware can be used for various purposes, such as logging, authentication, and error handling.

 

Example of Logging Middleware:

```javascript

const express = require('express');

const app = express();

 

// Custom logging middleware

const logger = (req, res, next) => {

    console.log(`[${new Date().toUTCString()}] ${req.method} ${req.url}`);

    next(); // Pass control to the next middleware or route handler

};

 

app.use(logger);

 

// Your routes and other middleware go here

 

const PORT = 3000;

app.listen(PORT, () => {

    console.log(`Express server running at http://localhost:${PORT}/`);

});

```

 

Key Takeaways:

- Middleware functions are executed in the order they are declared.

- `next()` passes control to the next middleware or route handler.

 

 4.2 RESTful API with Express.js

 

 4.2.1 Setting Up RESTful Routes

 

Defining Routes for CRUD Operations:

- RESTful APIs follow a pattern of routes for Create, Read, Update, and Delete (CRUD) operations.

- Routes are defined using HTTP methods (GET, POST, PUT, DELETE).

 

Example of RESTful Routes in Express.js:

```javascript

const express = require('express');

const app = express();

 

// Route for fetching all items

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

    // Logic for fetching items

    res.json({ items: [...] });

});

 

// Route for creating a new item

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

    // Logic for creating a new item

    res.json({ message: 'Item created successfully' });

});

 

// Similar routes for updating and deleting items

 

const PORT = 3000;

app.listen(PORT, () => {

    console.log(`Express server running at http://localhost:${PORT}/`);

});

```

 

Key Takeaways:

- RESTful routes follow a structured approach for different operations.

- Express.js provides a clean syntax for defining routes.

 

 4.2.2 Data Persistence with MongoDB

 

Integrating MongoDB with Express.js:

- MongoDB is a popular NoSQL database often used with Node.js applications.

- Mongoose, a MongoDB object modeling tool, simplifies database operations.

 

Performing Basic CRUD Operations:

- Connect to MongoDB, define a schema, and perform Create, Read, Update, and Delete (CRUD) operations.

 

Example of Data Persistence with MongoDB:

```javascript

const express = require('express');

const mongoose = require('mongoose');

const app = express();

 

// Connect to MongoDB

mongoose.connect('mongodb://localhost:27017/mydatabase', { useNewUrlParser: true, useUnifiedTopology: true });

 

// Define a schema

const itemSchema = new mongoose.Schema({

    name: String,

    description: String,

});

 

// Create a model based on the schema

const Item = mongoose.model('Item', itemSchema);

 

// Route for fetching all items from MongoDB

app.get('/api/items', async (req, res) => {

    try {

        const items = await Item.find();

        res.json({ items });

    } catch (error) {

        res.status(500).json({ error: 'Internal Server Error' });

    }

});

 

// Similar routes for creating, updating, and deleting items

 

const PORT = 3000;

app.listen(PORT, () => {

    console.log(`Express server running at http://localhost:${PORT}/`);

});

```

 

Key Takeaways:

- Mongoose simplifies MongoDB interactions in Node.js applications.

- Async/await syntax is used for handling asynchronous database operations.

 

Conclusion

Congratulations! You've mastered the art of building HTTP servers and crafting RESTful APIs with Node.js. Armed with this knowledge, you're ready to embark on sophisticated web development projects. As you continue your journey, keep exploring advanced concepts, experimenting with different technologies, and building impactful applications. Happy coding!