October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk6 min

Build a Node.js REST API: Routes, Methods, Validation, and Security

A practical guide to Node.js REST API contracts, routes, HTTP semantics, validation, error responses, and security using node:http or Express.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To build a REST API with Node.js, define the resources and HTTP contract first, then implement the routes with either the low-level built-in node:http module or a framework such as Express. Use HTTP methods according to their standardized meaning, validate every untrusted request, return outcome-specific status codes, and keep authentication separate from permission checks on individual resources.

How do I build a REST API with Node.js?

Start by deciding what resources the API exposes and what representations clients can send and receive. REST does not require a particular Node.js framework, folder layout, database, or authentication product. Those are implementation choices; the public contract is what lets a client use the API predictably.

As an Amazon Associate I earn from qualifying purchases.

For example, a widgets API might expose a collection at /widgets and an individual resource at /widgets/{id}. Specify which fields a client may submit, which content types are accepted, what a successful response contains, and how errors are represented. The routes below illustrate a conventional contract, not the only valid design.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Method and route Contract example Typical outcome
GET /widgets Retrieve the widget collection. No state change is requested. 200 OK with the collection representation.
GET /widgets/{id} Retrieve one widget by identifier. 200 OK with the widget, or 404 Not Found if it does not exist.
POST /widgets Create a widget from an accepted request representation, such as JSON. 201 Created, commonly with a Location header identifying the new resource.
PUT /widgets/{id} Replace the target widget’s current representation with the submitted representation. A success status appropriate to whether the API created or updated the target; validation or existence failures use an error status.
DELETE /widgets/{id} Remove the target widget if the caller is permitted to do so. A success status indicating the result, or an appropriate error if it cannot be removed.

These meanings are grounded in RFC 9110, HTTP Semantics. GET is safe: a client can request it without asking the server to change state. RFC 9110 explains that safe methods let automated retrieval and cache prefetching operate without fear of causing harm. Do not put a destructive or state-changing operation behind GET.

PUT means replacing all current representations of the target resource with the request content. If your API instead supports partial updates, define that contract explicitly rather than treating PUT as a generic partial-edit verb. POST is commonly used for creation or resource-specific processing, but clients should not automatically retry a non-idempotent request unless they know its semantics are idempotent or can determine the original was not applied. Retry safety depends on the operation contract.

Should I use node:http or Express?

Node.js supplies HTTP server and client primitives, including message parsing and streaming. Its documentation describes the HTTP API as deliberately low-level: it does not parse application body content for you. Express adds method-and-path routing and middleware composition. Neither choice is mandated by REST.

Concern Built-in node:http Express
Routing You implement route matching and method handling. Register handlers with method-and-path APIs such as app.get() and app.post().
Request body You consume the request stream and implement parsing and limits. You select and configure middleware for the request representations you accept.
Middleware and conventions You build the composition and response conventions the application needs. Middleware provides a composition mechanism for shared request processing and error handling.
Performance winner Not established universally by these sources; it depends on workload and implementation. Not established universally by these sources; it depends on workload and implementation.

Use node:http when direct control over the HTTP layer and the responsibility for implementing its surrounding conventions suit the project. Choose Express when its route registration and middleware model fit the application. The current Node.js HTTP API documentation shows both CommonJS and ECMAScript module examples; use the syntax that matches the project’s module configuration.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How do I create REST API routes in Express?

Express maps HTTP methods and paths to handlers, while middleware can perform shared work such as parsing supported JSON bodies. This small example shows route shape and response behavior; a production handler must call its persistence layer and enforce the validation and authorization rules described below.

const express = require('express');
const app = express();

app.use(express.json({ limit: '32kb' }));

app.get('/widgets/:id', async (req, res, next) => {
  try {
    const widget = await findWidget(req.params.id);
    if (!widget) {
      return res.status(404).json({ error: { code: 'not_found', message: 'Widget not found' } });
    }
    res.status(200).json(widget);
  } catch (err) {
    next(err);
  }
});

app.post('/widgets', async (req, res, next) => {
  try {
    const input = validateWidgetInput(req.body);
    const widget = await createWidget(input);
    res.location(`/widgets/${encodeURIComponent(widget.id)}`)
      .status(201)
      .json(widget);
  } catch (err) {
    next(err);
  }
});

The example assumes that the application has defined findWidget, validateWidgetInput, and createWidget; their behavior is part of the API contract, not something Express supplies. Configure body parsing only for content types the endpoint accepts, and ensure request-size limits align with the product’s expected payloads. See the Express routing guide for method-and-path route registration.

In current Express guidance, rejected promises from async route handlers are forwarded into error handling. The explicit try/catch and next(err) above make that flow visible and compatible with handlers that forward errors themselves; use the approach documented for the Express version in your project. A final error middleware can produce the application’s stable public error shape:

app.use((err, req, res, next) => {
  if (res.headersSent) return next(err);

  const status = Number.isInteger(err.status) ? err.status : 500;
  if (status >= 500) {
    console.error(err); // Keep diagnostic details on the server.
  }
  res.status(status).json({
    error: {
      code: status >= 500 ? 'internal_error' : (err.code || 'request_error'),
      message: status >= 500 ? 'An unexpected error occurred' : err.message
    }
  });
});

This is an error-response pattern, not a complete error taxonomy: the application must map validation, authorization, and other known failures to deliberate status codes. Express’s error-handling guide describes synchronous errors and rejected promises flowing into error handling.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

What HTTP methods and status codes should I use?

Return a status that tells the client what happened. In particular, do not report every error as 404 or every successful operation as 200. Choose codes as part of the endpoint contract and include useful headers where appropriate, such as Location after creation.

Outcome Status Meaning for the client
Resource created 201 Created The request created a resource; a Location header can identify it.
Malformed or invalid request 400 Bad Request The client needs to correct the request.
Missing or invalid authentication 401 Unauthorized The request lacks acceptable authentication credentials.
Authenticated caller lacks permission 403 Forbidden The caller is not allowed to perform the requested operation.
Resource not found 404 Not Found The target resource is unavailable at the requested route.
Method unsupported for route 405 Method Not Allowed The route does not support the method used.
Request body exceeds configured limit 413 Content Too Large The client must send a smaller request.
Unsupported request media type 415 Unsupported Media Type The endpoint does not accept the request’s representation format.
Rate limit reached 429 Too Many Requests The client should reduce or delay requests according to the API’s policy.
Unexpected server failure 500 Internal Server Error The server failed; the public response should not expose internal details.

For errors, use a stable response structure with a machine-readable code and a safe, client-useful message. Keep stack traces, database messages, and other implementation details in server-side diagnostics instead of returning them. The OWASP REST Security Cheat Sheet recommends semantically appropriate responses and generic error messages that do not reveal internal hints.

How should I validate and secure a Node.js API?

Validate the representation before using it

Treat path parameters, query parameters, headers, and request bodies as untrusted. For every field the endpoint accepts, define its type, format, allowed range, and maximum length; reject unexpected fields where they are not part of the contract. Validate the parsed value rather than assuming JSON parsing makes it safe.

  • Document supported request content types for each body-bearing route.
  • Reject unsupported content types with 415 Unsupported Media Type.
  • Set a request-size limit and return 413 Content Too Large when a payload exceeds it.
  • Return 400 Bad Request for malformed or invalid input, with enough detail to correct the request but no sensitive internals.
  • Set the response Content-Type to match the representation you actually return; do not copy the client’s Accept header blindly.

Authenticate, then authorize the requested operation

Authentication establishes who is making a request; authorization determines what that identity may do. Check permission for the specific object and operation, not just whether a caller has a valid session or token. Keep passwords, API keys, and tokens out of URL paths and query strings, where URLs can be captured in logs. Send credentials in suitable headers or request bodies according to the contract and method.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Constrain browser and operational exposure

Allow only the CORS origins required by the application rather than treating every origin as acceptable. Restrict management endpoints, and record security-relevant events while sanitizing log data so attacker-controlled values cannot inject misleading log entries. Browser-oriented security headers may matter for responses consumed by browsers; they are not automatically protective for APIs used exclusively by non-browser clients. OWASP’s REST Security Cheat Sheet covers these controls alongside input constraints and error handling.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.