Standing up a working web server in Express takes about ten lines. That simplicity is intentional, Express wants you spending time on your application logic, not on boilerplateWhat is boilerplate?Repetitive, standardized code that follows a known pattern and appears in nearly every project - like setting up a server or wiring up database connections.. In this lesson you will write that first server, then dig into the two objects you will use in every single route you ever write: req and res.
Creating the server
Create a file called index.js and paste this in:
import express from 'express';
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});Run it with:
node index.jsOpen your browser to http://localhost:3000 and you will see "Hello World!". That is your server. Four meaningful lines of code, and you have a working HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. server running in Node.js.
app.listen() calls the underlying http.createServer() from Node.js. Express does not reinvent the wheel, it wraps it with a cleaner API.The req object
req is short for request. Every time a browser or APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. client hits your server, Express builds an req object from the raw HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. request and hands it to your route handlerWhat is route handler?A Next.js file named route.js inside the app/ directory that handles HTTP requests directly - the App Router equivalent of API routes.. Here is a tour of the most useful properties:
app.get('/inspect', (req, res) => {
console.log(req.method); // 'GET'
console.log(req.path); // '/inspect'
console.log(req.url); // '/inspect?foo=bar' (includes query string)
console.log(req.query); // { foo: 'bar' } from ?foo=bar
console.log(req.headers); // All HTTP headers as an object
console.log(req.get('User-Agent')); // One specific header
console.log(req.ip); // Client IP address
res.send('Logged to console');
});You will use req.query constantly for things like paginationWhat is pagination?Splitting a large set of results into smaller pages so the server and client only handle a manageable chunk at a time. (?page=2&limit=10) and filters. req.headers matters when you start building authenticationWhat is authentication?Verifying who a user is, typically through credentials like a password or token. with tokens.
The res object
res is short for response. It is your toolkit for building the reply you send back to the client. The most important methods:
app.get('/demo', (req, res) => {
// Send a plain text or HTML string
res.send('Simple text response');
// Send JSON - automatically sets Content-Type: application/json
res.json({ message: 'Hello', ok: true });
// Set a status code (chain with send or json)
res.status(404).send('Not found');
res.status(201).json({ id: 42, created: true });
// Redirect the client to another URL
res.redirect('/new-url');
res.redirect(301, '/permanent-redirect');
// Set a custom response header
res.set('X-Powered-By', 'My Express App');
});res.send() followed by res.json() in the same handler will throw a "headers already sent" error. Express sends the response and closes the connection, you cannot reopen it.Common response methods at a glance
| Method | What it sends | Content-Type set automatically? |
|---|---|---|
res.send(string) | Plain text or HTML | Yes (text/html) |
res.json(object) | JSON-encoded object | Yes (application/json) |
res.sendFile(path) | A file from disk | Yes (based on extension) |
res.redirect(url) | HTTP redirect | N/A |
res.status(code) | Sets the status code (chainable) | No |
Combining routes on one path
Sometimes you want a single URL to handle multiple HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. methods. Instead of writing app.get and app.post separately, you can chain them with app.route():
app.route('/users')
.get((req, res) => {
res.json([{ id: 1, name: 'Alice' }]);
})
.post((req, res) => {
res.status(201).json({ id: 2, name: 'Bob' });
});This keeps related handlers together and makes your route file easier to scan.