Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 5

Building Your First Express Server

Recommended resources

Introduction

In the previous lesson, you created a .gitignore file to ensure sensitive data like your .env file and bulky folders like node_modules are never committed to your repository. Your project is now properly configured for version control.

This lesson completes our initial setup sprint. You will write the core code to instantiate and run your Express server. Specifically, you will:

  1. Create the Express application instance.
  2. Add the essential express.json() middleware, which is non-negotiable for building a REST API.
  3. Start the server, making it listen for requests on the port defined in your .env file.

We will implement a professional pattern that separates the application definition from the server startup logic. This separation is critical for automated testing, which we will cover in later modules.


1. Defining the Application (src/app.js)

First, we'll create a file dedicated to defining the Express application and its middleware.

Action: Create the Application File

  1. In your src/ directory, create a new file named app.js.
  2. Add the following code to src/app.js:
const express = require('express');

// Create the Express app instance
const app = express();

// Middleware to parse JSON request bodies
app.use(express.json());

// A simple route for the root to confirm the server is running
app.get('/', (req, res) => {
  res.status(200).json({ message: 'API is running' });
});

module.exports = app;

What is express.json()?

The line app.use(express.json()); is a crucial piece of middleware. A REST API communicates using JSON. When a client sends a POST or PUT request with a JSON payload in its body, this middleware parses that raw JSON text into a JavaScript object and attaches it to the request object at req.body. Without it, req.body would be undefined, and you wouldn't be able to access any data sent by the client.

Express.js JSON Middleware Configuration
This image highlights the exact pattern for adding the JSON parsing middleware to your Express application. This line enables your server to understand the data sent by API clients.

To hear this explained, the following short clip is very direct.

Learn Express JS In 35 Minutes

This clip from Web Dev Simplified provides a concise explanation of why express.json() is used.

Watch from 0:34:37 to 0:34:56. The key takeaway is that this middleware is for parsing JSON information from the request body, which is standard for APIs.


2. Starting the Server (server.js)

Now, we'll create a separate file whose only job is to start the server. This file will import the app we just defined and tell it to start listening for requests.

Action: Create the Server File

  1. In your project's root directory (the same level as package.json), create a new file named server.js.
  2. Add the following code to server.js:
// This must be the first line to ensure environment variables are loaded
require('dotenv').config();

const app = require('./src/app');

// Use the PORT from .env, or 5000 as a default
const PORT = process.env.PORT || 5000;

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

The app.js / server.js Pattern

You now have two files managing the server:

  • src/app.js: Defines the Express application, its middleware, and its routes. It exports the app object.
  • server.js: Imports the app object, reads the port from the environment, and starts the server.

This separation is a production-ready pattern. It allows you to import app.js in your test files without actually starting the server, giving you full control during testing. The following resource shows this exact structure.

From Zero to Production: Building a REST API

This article from DEV Community demonstrates the app.js / server.js pattern. Compare the two code blocks with the files you just created.

In the article section titled '4. Creating the Express Application', examine the first code block (src/app.js) and the second (server.js). This reinforces the separation of concerns: one file defines the app, the other runs it. Note that we will add the other middleware like cors and routes in upcoming lessons.


3. Running and Verifying Your Server

Let's bring your server to life.

Step 1: Update your .env file

Ensure your .env file in the root directory contains the port definition:

PORT=5000

Step 2: Add a Start Script

In your package.json file, add a start script. This is the standard command for running a Node.js application.

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "start": "node server.js"
},

Step 3: Run the Server

Open your terminal in the project's root directory and run the script:

npm start

You should see the confirmation message in your console:

Server is running on port 5000

Your server is now running! You can open a web browser and navigate to http://localhost:5000. You should see the JSON response: {"message":"API is running"}.

To stop the server, go back to your terminal and press Ctrl+C.


Conclusion

Congratulations, you have a running Node.js and Express server! You've successfully completed the entire project setup module.

Key Takeaways:

  • The Express application is created by calling const app = express().
  • The app.use(express.json()) middleware is mandatory for parsing JSON request bodies in a REST API.
  • Separating your application logic (app.js) from your server startup (server.js) is a professional standard that enables easier testing.
  • The server is started with app.listen(), using process.env.PORT to allow for flexible deployment configurations.
  • npm start is the conventional command to run your application.

With the server foundation now solidly in place, we can move on to the next critical component. In the next module, you'll connect this application to a MongoDB database using Mongoose, define a data schema, and create a model. This will prepare you to build the core CRUD (Create, Read, Update, Delete) functionality of your API.