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.

Service (.service.js)

Services are where Knex lives. One service module per resource encapsulates queries, transactions, and business rules. Controllers stay readable because they only orchestrate service calls and map errors to HTTP responses.

1 topic(s) on this page.

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