{"id":18230454,"url":"https://github.com/benc-uk/nodejs-api-starter","last_synced_at":"2026-05-06T04:07:14.853Z","repository":{"id":44214873,"uuid":"220822061","full_name":"benc-uk/nodejs-api-starter","owner":"benc-uk","description":"Starter template app for a Node.js CRUD REST API using MongoDB \u0026 Mongoose","archived":false,"fork":false,"pushed_at":"2023-01-24T00:45:16.000Z","size":1014,"stargazers_count":1,"open_issues_count":15,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-08T09:49:25.097Z","etag":null,"topics":["express","mongodb","nodejs","rest-api"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benc-uk.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-11-10T17:08:46.000Z","updated_at":"2022-07-06T08:08:56.000Z","dependencies_parsed_at":"2023-01-31T13:45:22.204Z","dependency_job_id":null,"html_url":"https://github.com/benc-uk/nodejs-api-starter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/benc-uk/nodejs-api-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benc-uk%2Fnodejs-api-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benc-uk%2Fnodejs-api-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benc-uk%2Fnodejs-api-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benc-uk%2Fnodejs-api-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benc-uk","download_url":"https://codeload.github.com/benc-uk/nodejs-api-starter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benc-uk%2Fnodejs-api-starter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32677955,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T02:33:58.958Z","status":"ssl_error","status_checked_at":"2026-05-06T02:33:39.611Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["express","mongodb","nodejs","rest-api"],"created_at":"2024-11-04T11:04:15.756Z","updated_at":"2026-05-06T04:07:14.826Z","avatar_url":"https://github.com/benc-uk.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Node.js API Starter Template\nThis is a starter template app for a generic REST API. It is written in Nodejs \u0026 Express, uses MongoDB at the backend and has a standard set of CRUD operations.\n\nFeatures:\n- Separation of controllers, services, models \u0026 routes\n- [Mongoose](https://mongoosejs.com/) for MongoDB interaction\n- Unit tests via Mocha, [SuperTest](https://www.npmjs.com/package/supertest) and [mongodb-memory-server](https://www.npmjs.com/package/mongodb-memory-server)\n- [Istanbul/nyc](https://www.npmjs.com/package/nyc) for code coverage\n- Swagger auto generation \u0026 Swagger UI using [express-swagger-generator](https://www.npmjs.com/package/express-swagger-generator)\n- A standard Dockerfile\n- An example model/controller/service - called 'thing'\n\nThis repo can be cloned/copied to bootstrap new projects\n\n\n# Project Structure\nThe project follows a fairly standard MVC style structure, except there are no views. This being an API, all data is returned as JSON\n\n- `controllers/` - controllers, including base **Controller** class. HTTP interface layer\n- `models/` - models, classes should initalize a Mogoose schema, and return instances of Mongoose models\n- `services/` - services, carry out CRUD operations against the database via the models. Includes base **Service** class\n- `core/` - main database connection and app routes\n\nA **Service** wraps a single **Model**, and a **Controller** wraps a single **Service**\n\nThe base classes in `services/service.js` and `controllers/controller.js` contain implementations and methods for a standard CRUD style REST API. This means adding your own should require the minimum of code. See [usage and example](#example)\n\n## Service Layer - Querying Models\nMost methods (`insert`, `fetchOne`, `update`, `delete`) of the 'Service' class work against the database much as expected, the query method requires some explanation. The `query` method should be passed a HTTP request query object (i.e. `req.query`)\n\nThree query URL parameters are supported, all are optional:\n- `filter` - A query string passed to [mongoose-query-parser](https://www.npmjs.com/package/mongoose-query-parser), e.g. `foo=bar` or `name=ben%26score\u003e=25`. This is effectively a nested query string, so URI encode any ampersands as %26 \n- `limit` - Limit number of results returned\n- `skip` - Skip a number of results, use for pagination\n\nNote. Omitting all params (i.e. no query string at all) results in all documents of the given model being returned from the DB\n\nURL examples:\n- `/api/things?cheese=cheddar`\n- `/api/things?name=ben%26score\u003e=25\u0026limit=5`\n- `/api/things?skip=100\u0026limit=50`\n\n## Main Server / App Entrypoint\nThe app is started via `server.js` in the root of the project, which can be started with `node server.js` or `npm start`. \nThe server is a fairly standard Express app, additional optional features include loading dotenv files, configuring logging (via morgan) and swagger auto generation.\n\nThe server will try to connect to MongoDB on startup, if it can't connect the app will terminate.\n\nThe `etc/server-minimal.js` file is an alternative version with all the optional sections removed, leaving bare minimum to start the app.\n\n\n# Configuration\nConfiguration is done via environmental variables, the dotenv library is included and will load any `.env` file found, a sample env file is included for reference.\n\nThe following environmental variables are used:\n\n| Variable | Description | Type | Default |\n|----------|-------------|------|---------|\n|PORT|Port to listen on for HTTP requests|integer|3000|\n|MONGO_CONNSTR|MongoDB connection string URL [📘](https://docs.mongodb.com/manual/reference/connection-string/)|string|mongodb://localhost/|\n|MONGO_CONNECT_TIMEOUT|Timeout when first connecting to MongoDB, in millisecs|integer|30000|\n\nIn place of `MONGO_CONNSTR` the variables `MONGO_CONNECTION` or `MONGO_URL` can also be used instead.\n  \n## Supplied NPM Scripts\n- `npm start` - Start the app\n- `npm run watch` - Start the app, listen to code changes and restart with nodemon\n- `npm test` - Run Mocha unit tests\n- `npm run test-html` - Run unit tests and output report in HTML format\n- `npm run test-junit` - Run unit tests and output report in JUnit format\n- `npm run coverage` - Generate code coverage report\n- `npm run cleanup` - Cleanup output directories from unit tests/coverage\n\n \n# Usage and 'Thing' Placeholder\nThe template comes with a 'thing' entity which simply serves as a placeholder and example for adding your own models, entities and APIs. \n\nTo start using the template replicate the code in these files:\n- `models/thing.js`\n- `controllers/thing-controller.js`\n- `services/thing-service.js`\n- `test/api-thing.spec.js`\n\nCopy, rename and edit these files to new names and change classes as required.  \n\n### Example - adding 'Foo' entity and API\n\nA new Foo **Controller** in `controllers/foo-controller.js`\n```js\nclass FooController extends Controller {\n  constructor(service) { \n    super(service);\n  }\n}\n```\n\nCreate a new Foo model in `models/foo.js`, eg.\n\n```js\nconst mongoose = require ('mongoose');\n\nclass Foo {\n  initSchema() {\n    mongoose.model('foo', new mongoose.Schema({\n      name: { type: String, required: true },\n    });\n  }\n\n  // Return an instance of Thing model\n  getInstance() {\n    if(!mongoose.modelNames().includes('foo'))\n      this.initSchema();\n\n    return mongoose.model('foo');\n  }\n}\n\nmodule.exports = Foo;\n```\n\nA new Foo **Service** in `services/foo-service.js`\n```js\nconst Foo = require('../models/foo');\nclass FooService extends Service {\n  constructor() {\n    const foo = new Foo().getInstance();\n    super(foo);\n  }\n};\n```\n\nIn `core/routes.js` add an instance of your new controller, e.g.\n\n```js\nconst FooController = require('../controllers/foo-controller');\nconst FooService = require('../services/foo-service');\nconst fooController = new FooController(new FooService());\n```\n\nAnd expose routes of that controller in `core/routes.js` as follows:\n```js\napp.get('/api/foo',        fooController.query);\napp.get('/api/foo/:id',    fooController.get);\napp.post('/api/foo',       fooController.create);\napp.put('/api/foo/:id',    fooController.update);\napp.delete('/api/foo/:id', fooController.delete);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenc-uk%2Fnodejs-api-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenc-uk%2Fnodejs-api-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenc-uk%2Fnodejs-api-starter/lists"}