Well-structured backends separate concerns: routers define URLs, controllers translate HTTP to application calls, services own data access, and middleware handles cross-cutting behavior (validation, 404, errors). Study these patterns to keep files small, testable, and aligned with REST conventions.

How to use a service layer — Intermediate

Isolate database and business logic in services called from controllers or routers.
Learn: Services are the place for Knex queries, transactions, and business rules. Returning plain objects (or throwing errors) keeps controllers simple and makes services testable without spinning up HTTP.

Supplementary examples

Service function with Knex

const knex = require("../db/connection");

function listByUser(userId) {
  return knex("pastes").where({ user_id: userId }).orderBy("created_at", "desc");
}

module.exports = { listByUser };

Throw when resource missing

async function read(pasteId) {
  const row = await knex("pastes").where({ paste_id: pasteId }).first();
  if (!row) {
    const err = new Error("Paste not found");
    err.status = 404;
    throw err;
  }
  return row;
}

Course example

{
"data": [
{
"product_sku": "giUGNvnn8Q",
"product_title": "Reserved for the Dog Cushion",
"total_weight_in_lbs": "1100.00"
},
{
"product_sku": "ay6srUUaht",
"product_title": "Laudable Accomplishments of the Warrior: A Fate Forfeit",
"total_weight_in_lbs": "898.01"
},
...

Additional references & examples

← All Service (.service.js) · Server Architecture / Routes