{"id":21826852,"url":"https://github.com/tejbirringtm/essentialserver","last_synced_at":"2025-03-21T12:21:31.692Z","repository":{"id":265014917,"uuid":"894820572","full_name":"TejBirringTM/EssentialServer","owner":"TejBirringTM","description":"Just your everyday Node.js server written in TypeScript, based on the Express.js web framework.","archived":false,"fork":false,"pushed_at":"2024-12-13T05:42:39.000Z","size":79,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-26T08:26:27.714Z","etag":null,"topics":["express","express-js","expressjs","node-js","nodejs","rest","rest-api","restful","restful-api","server","serverless","service","services","template","types","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TejBirringTM.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-27T03:48:17.000Z","updated_at":"2024-12-13T05:42:43.000Z","dependencies_parsed_at":"2025-01-26T08:34:31.026Z","dependency_job_id":null,"html_url":"https://github.com/TejBirringTM/EssentialServer","commit_stats":null,"previous_names":["tejbirringtm/essentialserver"],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TejBirringTM%2FEssentialServer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TejBirringTM%2FEssentialServer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TejBirringTM%2FEssentialServer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TejBirringTM%2FEssentialServer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TejBirringTM","download_url":"https://codeload.github.com/TejBirringTM/EssentialServer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244795519,"owners_count":20511521,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","express-js","expressjs","node-js","nodejs","rest","rest-api","restful","restful-api","server","serverless","service","services","template","types","typescript"],"created_at":"2024-11-27T18:11:08.944Z","updated_at":"2025-03-21T12:21:31.649Z","avatar_url":"https://github.com/TejBirringTM.png","language":"TypeScript","readme":"# Essential Server (Node.js, Express.js, TypeScript)\n\n[__Essential Server__](https://github.com/TejBirringTM/EssentialServer) is just your everyday [Node.js](https://nodejs.org/) server written in [TypeScript](https://www.typescriptlang.org/), based on the [Express.js](https://expressjs.com/) web framework — designed to get new projects off the ground as quickly as possible.\n\n[See below on how to get started ASAP.](#getting-started)\n\n## Features\n\n### Validation and Parsing\n\n✅ Schema-validated environment variables (using [zod](https://www.npmjs.com/package/zod))\n\n✅ Deeply-engrained semantic versioning ([Semantic Version 2.0.0](https://semver.org/spec/v2.0.0.html))\n\n* Captures and validates `version` stipulated in `package.json` to avoid discrepancies\n\n✅ Advanced parsing of URL-encoded query strings for richer query data (using [qs](https://www.npmjs.com/package/qs))\n\n✅ JSON requests (`request.body`) and responses\n\n✅ Thorough schema validation of requests (using [zod](https://www.npmjs.com/package/zod))\n\n* __Route parameters:__ schema sensibly constrained to `Record\u003cstring, string\u003e`\n* __Query parameters:__ schema sensibly constrained to [qs](https://www.npmjs.com/package/qs)-compatible output\n* __Body:__ schema sensibly constrained to JSON-serialisable object\n\n### Logging\n\n✅ Automatic, configurable request logging (using [morgan](https://www.npmjs.com/package/morgan))\n\n### Error Handling\n\n✅ Basic error handling, out of the boxes\n\n* Throws `500 Internal Server Error` on exception.\n* If an Error object is caught, displays `error.message` in body of the error response.\n\n### Security\n\n✅ Appends \"best practice\" security headers (using [helmet](https://www.npmjs.com/package/helmet))\n\n✅ Implements Cross-Origin Resource Sharing (CORS) controls (using [helmet](https://www.npmjs.com/package/helmet) and [cors](https://www.npmjs.com/package/cors))\n\n✅ Rate limiting, out of the box (using [express-rate-limit](https://www.npmjs.com/package/express-rate-limit))\n\n* IP based.\n* Currently uses internal memory store.\n\n### Performance\n\n✅ Caching, out of the box\n\n* Useful `cacheHandler` middleware to enable appropriate response caching on individual routes or across router(s)\n    * Control own caching behaviour (through middleware options)\n    * Control caching behaviour of external caches (through middleware options pertaining to `Cache-Control` headers)\n* Currently uses internal memory store ([node-cache](https://www.npmjs.com/package/node-cache)).\n\n## Prerequisites\n\n* Node.js v22+\n\n## Getting Started\n\n### 1. Create a New Project\n\n#### Option A: Local Clone\n\n1. Using a terminal, run the command below to clone Essential Server into a new project directory: \n\n    `npx degit TejBirringTM/EssentialServer \u003cyour_project_name\u003e`\n\n2. Navigate to the local clone:\n\n    `cd \u003cyour_project_name\u003e`\n\n#### Option B: New GitHub Repository\n\n1. Navigate to the [Essential Server GitHub repository](https://github.com/TejBirringTM/EssentialServer).\n2. Click 'Use this template' followed by ;Create a new repository'.\n3. Follow the instructions provided by GitHub to clone Essential Server into a new repository for your project.\n4. Using a terminal, clone the newly-created project repository to your local machine.\n5. Navigate to the local clone:\n\n    `cd \u003cyour_project_name\u003e`\n\n### 2. Install Dependencies\n\nFrom the terminal, install project dependencies: `npm install`\n\n### 3. (Optional) Perform Sanity Checks\n\n1. Ensure all tests pass.\n\n    From the terminal, run:\n`npm test`\n\n    If any test fails, please [submit a report here.](https://github.com/TejBirringTM/EssentialServer/issues)\n\n2. Run the server and test its endpoints.\n\n    From the terminal, run: `npm run start`\n\n    You can test the server by sending HTTP requests to the endpoints implemented in `src/routes/*.ts` files from a HTTP client like [Insomnia](https://insomnia.rest/) or [Postman](https://www.postman.com/).\n\n    Once you're done, exit the server by pressing `Ctrl + C` while in the terminal.\n\n### 4. Implement Server\n\n__Congratulations!__\n\nNow, it's time for you to implement your own server!\n\n[See here for more information about this.](#how-to-use)\n\nWhile you are developing, you will find this command helpful to start the server; it will restart the server every time a source file is modified: `npm run dev`\n\n## How to Use\n\n### Folder Structure\n\nBefore proceeding, it would be a good idea to understand the folder structure of Essential Server:\n\n```\nsrc/\n├─ config/\n|  code that parses environment variables and \n|  exports a configuration object to the rest \n|  of the codebase.\n|\n├─ middlewares/\n|  top-level files export Express.js middleware(s)\n|  (i.e. route handler functions) for use by the\n|  server application, a router, or individual\n|  routes.\n|\n├─ routes/\n|  top-level files default export a Router\n|  object describing routes to serve.\n|  Note: the routers are loaded and served\n|  automatically!\n|\n├─ services/\n|  modules that provide foundational services\n|  to the rest of the system.\n|\n├─ utils/\n|  simple utility classes, modules, and functions; \n|  stateless and pure (i.e. no side effects).\n```\n\nThe `tests/` folder should follow the same pattern as the `src/` folder.\n\n### Configuration\n\nCurrently, all configurations (but one) are determined by the environment variables of the\nserver's execution environment. All environment variables are described in\n`src/config/schema.ts` – see the `describe(...)` calls.\n\n__Note:__ When running in `debug` mode, the `.env` file in the project's root directory will be loaded by default.\n\nThe other configuration used by the system is the `version` value from the project's `package.json` file. The version string must abide by [Semantic Version 2.0.0](https://semver.org/spec/v2.0.0.html). The 'major' part of the version will determine the base\npath of the server.\n\n__Example__\n\nIf `src/routes/public.ts` exports a route called `my/test/`, and the `version` number in `package.json` is set to `'2.4.1'`, the route will be served from `/api/v2/public/my/test/` (with or without the trailing `/`).\n\nThe general pattern for endpoints is: `/api/v\u003cversion_major\u003e/\u003crouter_file_name\u003e/\u003croute_path\u003e`\n\n#### Adding New Configurations\n\nTo add a new configuration, you should first append any new environment variables to the environment variables schema in `src/config/schema.ts`.\n\nThen, you should export the _parsed_ variable via the default export in `src/config/index.ts`\n\n__Example__\n\nIn `src/config/schema.ts`:\n\n```ts\nexport const envSchema = z.object({\n  // ... omitted for brevity\n  \n  COOLNESS: z.enum(['not cool', 'cool', 'very cool', 'uber cool'])\n    .describe('The perceived level of coolness of the server.')\n    .default('uber cool')\n\n  // ... omitted for brevity\n });\n```\n\nIn `src/config/index.ts`:\n```ts\nconst config = {\n    env: env.NODE_ENV,\n    port: env.PORT,\n    // ... omitted for brevity\n    perception: {\n        of: {\n            server: {\n                coolness: env.COOLNESS,\n            },\n        },\n    },\n} as const;\n\nexport default config;\n```\n\n### Development\n\n#### Adding New Routes\n\nTo add a new route, either:\n\na. Add routes to an existing router object default exported by a top-level source file in the `src/routes` folder.\n\nb. Create a new source file in the `src/routes` folder and `export default` a new router object from it.\n\n__Note:__ The general pattern for endpoints is: `/api/v\u003cversion_major\u003e/\u003crouter_file_name\u003e/\u003croute_path\u003e`\n\n##### Adding Validated Routes\n\n\n##### Adding Unvalidated Routes\n\n\n### Testing\n\n_Test infrastructure is currently being implemented._\n\n### Deployment\n\nEssential Server is designed to allow maximum flexibility around deployment by not making design decisions that might ordinarily restrict deployment options.\n\n## Issues\n\nIf you encounter a bug or want to see something added or improved, please go ahead and [open an issue!](https://github.com/TejBirringTM/EssentialServer/issues)\n\nIf you need help with something, feel free to [start a discussion!](https://github.com/TejBirringTM/EssentialServer/discussions)\n\n## Contributing\n\nThank you, feel free!\n\nContributions can take many forms, from code for bug fixes and enhancements, to documentation work, writing additional tests, triaging incoming pull requests and issues, and more!\n\nBefore submitting a PR, ensure that:\n\n1. Code is functional.\n2. Code is linted.\n3. Code passes all tests.\n4. Any requisite updates or additions to documentation have been made.\n\nFeel free to [reach out](mailto:tejbirring@gmail.com?subject=The%20Essential%20Server%20Project\u0026body=Hey%20Tej%2C%0A%0A...) if you're not sure!\n\n## License\n```\nMIT License\n\nCopyright © 2024 Tej Birring\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftejbirringtm%2Fessentialserver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftejbirringtm%2Fessentialserver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftejbirringtm%2Fessentialserver/lists"}