{"id":21232492,"url":"https://github.com/tugascript/nestjs-graphql-monolith-express","last_synced_at":"2025-07-10T17:31:13.285Z","repository":{"id":65383503,"uuid":"531145365","full_name":"tugascript/nestjs-graphql-monolith-express","owner":"tugascript","description":"Nestjs with Express, GraphQL Monolith Template ","archived":true,"fork":false,"pushed_at":"2023-03-17T04:09:36.000Z","size":2885,"stargazers_count":6,"open_issues_count":11,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-06T16:12:34.720Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/tugascript.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":"2022-08-31T15:29:34.000Z","updated_at":"2025-03-16T11:40:44.000Z","dependencies_parsed_at":"2023-02-17T10:30:24.287Z","dependency_job_id":null,"html_url":"https://github.com/tugascript/nestjs-graphql-monolith-express","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":"tugascript/nestjs-graphql-fastity-template","purl":"pkg:github/tugascript/nestjs-graphql-monolith-express","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tugascript%2Fnestjs-graphql-monolith-express","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tugascript%2Fnestjs-graphql-monolith-express/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tugascript%2Fnestjs-graphql-monolith-express/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tugascript%2Fnestjs-graphql-monolith-express/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tugascript","download_url":"https://codeload.github.com/tugascript/nestjs-graphql-monolith-express/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tugascript%2Fnestjs-graphql-monolith-express/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264618972,"owners_count":23638380,"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":[],"created_at":"2024-11-20T23:52:22.597Z","updated_at":"2025-07-10T17:31:11.703Z","avatar_url":"https://github.com/tugascript.png","language":"TypeScript","funding_links":["https://github.com/sponsors/B4nan","https://opencollective.com/libvips"],"categories":[],"sub_categories":[],"readme":"# NestJS GraphQL Monolith Express\n\n## Description\n\nFull [NodeJS](https://nodejs.org/en/) boilerplate of a [NestJS](https://nestjs.com/) [GraphQL](https://graphql.org/)\nmonolithic\nbackend API using [PostgreSQL](https://www.postgresql.org/) as the database.\n\n### Technologies\n\nIn terms of languages this template takes\na [NestJS GraphQL Code First Approach](https://docs.nestjs.com/graphql/quick-start#code-first), so it's fully written in\n[TypeScript](https://www.typescriptlang.org/).\n\nIn terms of frameworks it uses:\n\n* [NestJS](https://nestjs.com/) as the main NodeJS framework;\n* [Express](http://expressjs.com/) as the HTTP and WS adapter;\n* [Apollo](https://www.apollographql.com/docs/apollo-server/integrations/middleware/#apollo-server-express) as the\n  GraphQL adapter for Express;\n* [MikroORM](https://mikro-orm.io/) as the ORM for interacting with the database;\n* [Sharp](https://sharp.pixelplumbing.com/) for image manipulation and optimization.\n\n### Features\n\n**Configuration** (adds most used config classes)**:**\n\n* Cache with [Redis](https://redis.io/);\n    - \u003csmall\u003eNOTE: There's a caveat as you need to specify cache control directive for it to work\u003c/small\u003e\n* GraphQL with subscriptions and [GraphQL through Websockets](https://www.npmjs.com/package/graphql-ws);\n* MikroORM with [SQLite](https://www.sqlite.org/index.html) in development and [PostgreSQL](https://www.postgresql.org/)\n  in production.\n\n**Authentication:**\n\n* [JWT](https://jwt.io/) Authentication (local [OAuth](https://oauth.net/2/)) for HTTP;\n* Custom Session Authentication for Websockets (based on Facebook Messenger Design);\n* Two-Factor authentication with email.\n\n**Uploader:**\n\n* Basic image only uploader with [Sharp](https://sharp.pixelplumbing.com/) optimizations for a generic S3 Bucket.\n\n**Pagination:**\n\n* Has the generics for Edges and Paginated types;\n* [Relay cursor pagination](https://relay.dev/graphql/connections.htm) function.\n\n## GraphQL Upload Configuration\n\nThis template uses the latest version of [GraphQL Upload](https://github.com/jaydenseric/graphql-upload). Unfortunately\nis uses [ECMAScript modules](https://nodejs.org/api/esm.html#modules-ecmascript-modules), and they're quite tricky to\nuse with most TypeScript frameworks. So, in order to make it\nwork I had to use these workarounds:\n\n- This template now only works with [Node](https://nodejs.org/en/) version 16 or higher;\n- For the library itself I use [dynamic imports](https://v8.dev/features/dynamic-import) to load both the middleware and\n  the Scalar.\n- In Jest I had to use the `--experimental-vm-modules` flag to make it work, so all your projects with this template\n  will need to use [Yarn](https://yarnpkg.com/) package manager. Now the test command looks something like this:\n\n```bash\n# I have changed it on the package.json file as well\n$ yarn node --experimental-vm-modules $(yarn bin jest) \n```\n\n- The UploadOptions interface now is local on the following file: `src/config/interfaces/upload-options.interface.ts`;\n- Since the GraphQLUpload scalar is now a dynamic import you'll need to use the uploadScalar util that is located on the\n  `src/uploader/utils/upload-scalar.util.ts` file on your Field decorators.\n\n## Module Folder Structure\n\nIn terms of folders each [module](https://docs.nestjs.com/modules) is divided as follows:\n\n\u003csup\u003e**NOTE:** this is only a recommendation you can always use your own approach as long as they work with\nNestJS.\u003c/sup\u003e\n\n```\nC:/home/user/Home/IdeProjects/{project-folder}/src/{module-name}:.\n├─── entities\n│    │ {something}.entity.ts\n│    ├─── gql:\n│    │     {something}.type.ts\n├─── interfaces\n│     {something}.interface.ts\n├─── enums\n│     {something}.enum.ts\n├─── dtos\n│     {something}.dto.ts\n├─── inputs\n│     {something}.input.ts\n├─── tests\n│     {something}.spec.ts\n│ {module-name}.module.ts\n│ {module-name}.service.ts\n│ {module-name}.resolver.ts\n```\n\n### Entities (entities):\n\n* Where you save all your entities;\n* The entities are the classes that represent the [database tables](https://mikro-orm.io/docs/defining-entities)\n  and the [Graphql Object Types](https://docs.nestjs.com/graphql/resolvers#object-types);\n* These are normally decorated with the [@Entity](https://mikro-orm.io/docs/defining-entities) decorator and the\n  [@ObjectType](https://docs.nestjs.com/graphql/resolvers#object-types) decorator;\n* \u003cins\u003eFile Extension:\u003c/ins\u003e {something}.entity.ts\n* **Gql (gql):**\n    - Where you save the [Generic Graphql Object Types](https://docs.nestjs.com/graphql/resolvers#generics) (ex:\n      PaginatedUsers, etc.);\n    - These are normally decorated with the\n      [@ObjectType](https://docs.nestjs.com/graphql/resolvers#object-types) decorator;\n    - \u003cins\u003eFile Extension:\u003c/ins\u003e {something}.type.ts\n\n### Interfaces (interfaces):\n\n* Where you save all the interfaces and TypeScript types;\n* \u003cins\u003eFile Extension:\u003c/ins\u003e {something}.interface.ts\n\n### Enums (enums):\n\n* Where you save all general enums and [Enum Type](https://docs.nestjs.com/graphql/unions-and-enums#code-first-1);\n* \u003cins\u003eFile Extension:\u003c/ins\u003e {something}.enum.ts\n\n### Dtos (dtos):\n\n* Where you save all the DTOs (Data Transfer Objects) mainly for your Queries;\n* These are normally decorated with\n  the [ArgsType](https://docs.nestjs.com/graphql/resolvers#dedicated-arguments-class) decorator;\n* \u003cins\u003eFile Extension:\u003c/ins\u003e {something}.dto.ts\n\n### Inputs (inputs):\n\n* Where you save all the [GraphQL Input Objects](https://docs.nestjs.com/graphql/mutations#code-first) mainly for\n  your Mutations;\n* These are normally decorated with\n  the [@InputType](https://docs.nestjs.com/graphql/mutations#code-first) decorator;\n* \u003cins\u003eFile Extension:\u003c/ins\u003e {something}.input.ts\n\n### Tests (tests):\n\n* Where you save all the unit tests for your module's [services](https://docs.nestjs.com/providers#services),\n  [resolvers](https://docs.nestjs.com/graphql/resolvers) and [controllers](https://docs.nestjs.com/controllers);\n* These are normally the spec files generated by the cli, but you still need to move them to this folder;\n* \u003cins\u003eFile Extension:\u003c/ins\u003e {something}.spec.ts\n\n### Optional Folders:\n\n* **Embeddables (embeddables):**\n    - Where you save all your [JSON Fields](https://www.geeksforgeeks.org/postgresql-json-data-type/) for your\n      database tables;\n    - These are normally decorated with the [@Embeddable](https://mikro-orm.io/docs/embeddables) decorator;\n    - \u003cins\u003eFile Extension:\u003c/ins\u003e {something}.embeddable.ts\n* **Guards (guards):**\n    - Where you save all your [NestJS Guards](https://docs.nestjs.com/guards) related to your module;\n    - \u003cins\u003eFile Extension:\u003c/ins\u003e {something}.guard.ts\n\n## Initial Set Up\n\n### Installation\n\n```bash\n$ yarn install\n```\n\n### Database Migrations\n\n```bash\n# creation\n$ yarn migrate:create\n# update\n$ yarn migrate:update\n```\n\n### Running the app\n\n```bash\n# production mode\n$ yarn start\n\n# watch mode\n$ yarn start:dev\n\n# debug mode\n$ yarn start:debug\n```\n\n## Local setup\n\n1. Create a repo using this template;\n2. Install the dependencies:\n\n```bash\n$ yarn install\n```\n\n3. Create a .env file with all the fields equal to the [example](.env.example).\n4. Run the app in development mode:\n\n```bash\n$ yarn start:dev\n```\n\n## Unit Testing\n\n### BEFORE EACH TEST (Individual or All):\n\n* Check if NODE_ENV is not production;\n* Remove the current test.db (if exits);\n* Create a new test.db.\n\n```bash\n# remove test.db\n$ rm test.db\n# create a new test.db\n$ yarn migrate:create\n```\n\n### All tests:\n\n```bash\n# unit tests\n$ yarn run test  --detectOpenHandles\n```\n\n### Individual test:\n\n```bash\n# unit tests\n$ yarn run test service-name.service.spec.ts --detectOpenHandles\n```\n\n## Deployment\n\n### Steps:\n\n1. Go to [DigitalOcean](https://www.digitalocean.com/), [Linode](https://www.linode.com/)\n   or [Hetzner](https://www.hetzner.com/);\n2. Create a server running [Ubuntu LTS](https://ubuntu.com/);\n3. Install [dokku](https://dokku.com/docs~v0.28.1/getting-started/installation/#1-install-dokku);\n4. Run the following commands on your server for dokku initial set-up:\n\n```bash\n$ cat ~/.ssh/authorized_keys | dokku ssh-keys:add admin\n$ dokku domains:set-global your-global-domain.com\n```\n\n5. Create a new app and connect git:\n\n```bash\n$ dokku apps:create app-name\n```\n\n6. Add the [Postgres plugin](https://github.com/dokku/dokku-postgres) to dokku, create a new PG instance and link it to\n   the app:\n\n```bash\n$ sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres\n$ dokku postgres:create app-name-db\n$ dokku postgres:link app-name-db app-name\n```\n\n7. Add the [Redis plugin](https://github.com/dokku/dokku-redis) to dokku, and create a new Redis instance and link it to\n   the app:\n\n```bash\n$ sudo dokku plugin:install https://github.com/dokku/dokku-redis.git redis\n$ dokku redis:create app-name-redis\n$ dokku redis:link app-name-redis app-name\n```\n\n8. Add all the other configurations as in the [example](.env.example) file:\n\n```bash\n$ dokku config:set app-name URL=https://your-domain.com ...\n```\n\n9. On the project folder on your local computer run the following commands:\n\n```bash\n$ git remote add dokku dokku@server-public-ip-address:app-name\n$ git push dokku main:master\n```\n\n10. Finally set up SSL and a domain for your app:\n\n```bash\n$ sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git\n$ dokku config:set --global DOKKU_LETSENCRYPT_EMAIL=your-email@your.domain.com\n$ dokku domains:set app-name your-domain.com\n$ dokku letsencrypt:enable app-name\n$ dokku letsencrypt:cron-job --add \n```\n\n## Support the frameworks used in this template\n\nNest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If\nyou'd like to join them, please [read more here](https://docs.nestjs.com/support).\n\nMikro-ORM is a TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. If you like\nMikroORM, give it a [star](https://github.com/mikro-orm/mikro-orm) on GitHub and\nconsider [sponsoring](https://github.com/sponsors/B4nan) its development!\n\n[Sharp](https://sharp.pixelplumbing.com/) is a high performance Node.js image processor. If you want\nto [support them.](https://opencollective.com/libvips)\n\n## License\n\nThis template is [MIT licensed](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftugascript%2Fnestjs-graphql-monolith-express","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftugascript%2Fnestjs-graphql-monolith-express","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftugascript%2Fnestjs-graphql-monolith-express/lists"}