Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tugascript/nestjs-graphql-monolith-express
Nestjs with Express, GraphQL Monolith Template
https://github.com/tugascript/nestjs-graphql-monolith-express
Last synced: about 2 months ago
JSON representation
Nestjs with Express, GraphQL Monolith Template
- Host: GitHub
- URL: https://github.com/tugascript/nestjs-graphql-monolith-express
- Owner: tugascript
- License: mit
- Created: 2022-08-31T15:29:34.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2023-02-01T19:58:14.000Z (almost 2 years ago)
- Last Synced: 2023-03-07T17:25:52.002Z (almost 2 years ago)
- Language: TypeScript
- Size: 3.65 MB
- Stars: 6
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# NestJS GraphQL Monolith Express
## Description
Full [NodeJS](https://nodejs.org/en/) boilerplate of a [NestJS](https://nestjs.com/) [GraphQL](https://graphql.org/)
monolithic
backend API using [PostgreSQL](https://www.postgresql.org/) as the database.### Technologies
In terms of languages this template takes
a [NestJS GraphQL Code First Approach](https://docs.nestjs.com/graphql/quick-start#code-first), so it's fully written in
[TypeScript](https://www.typescriptlang.org/).In terms of frameworks it uses:
* [NestJS](https://nestjs.com/) as the main NodeJS framework;
* [Express](http://expressjs.com/) as the HTTP and WS adapter;
* [Apollo](https://www.apollographql.com/docs/apollo-server/integrations/middleware/#apollo-server-express) as the
GraphQL adapter for Express;
* [MikroORM](https://mikro-orm.io/) as the ORM for interacting with the database;
* [Sharp](https://sharp.pixelplumbing.com/) for image manipulation and optimization.### Features
**Configuration** (adds most used config classes)**:**
* Cache with [Redis](https://redis.io/);
- NOTE: There's a caveat as you need to specify cache control directive for it to work
* GraphQL with subscriptions and [GraphQL through Websockets](https://www.npmjs.com/package/graphql-ws);
* MikroORM with [SQLite](https://www.sqlite.org/index.html) in development and [PostgreSQL](https://www.postgresql.org/)
in production.**Authentication:**
* [JWT](https://jwt.io/) Authentication (local [OAuth](https://oauth.net/2/)) for HTTP;
* Custom Session Authentication for Websockets (based on Facebook Messenger Design);
* Two-Factor authentication with email.**Uploader:**
* Basic image only uploader with [Sharp](https://sharp.pixelplumbing.com/) optimizations for a generic S3 Bucket.
**Pagination:**
* Has the generics for Edges and Paginated types;
* [Relay cursor pagination](https://relay.dev/graphql/connections.htm) function.## GraphQL Upload Configuration
This template uses the latest version of [GraphQL Upload](https://github.com/jaydenseric/graphql-upload). Unfortunately
is uses [ECMAScript modules](https://nodejs.org/api/esm.html#modules-ecmascript-modules), and they're quite tricky to
use with most TypeScript frameworks. So, in order to make it
work I had to use these workarounds:- This template now only works with [Node](https://nodejs.org/en/) version 16 or higher;
- For the library itself I use [dynamic imports](https://v8.dev/features/dynamic-import) to load both the middleware and
the Scalar.
- In Jest I had to use the `--experimental-vm-modules` flag to make it work, so all your projects with this template
will need to use [Yarn](https://yarnpkg.com/) package manager. Now the test command looks something like this:```bash
# I have changed it on the package.json file as well
$ yarn node --experimental-vm-modules $(yarn bin jest)
```- The UploadOptions interface now is local on the following file: `src/config/interfaces/upload-options.interface.ts`;
- Since the GraphQLUpload scalar is now a dynamic import you'll need to use the uploadScalar util that is located on the
`src/uploader/utils/upload-scalar.util.ts` file on your Field decorators.## Module Folder Structure
In terms of folders each [module](https://docs.nestjs.com/modules) is divided as follows:
**NOTE:** this is only a recommendation you can always use your own approach as long as they work with
NestJS.```
C:/home/user/Home/IdeProjects/{project-folder}/src/{module-name}:.
├─── entities
│ │ {something}.entity.ts
│ ├─── gql:
│ │ {something}.type.ts
├─── interfaces
│ {something}.interface.ts
├─── enums
│ {something}.enum.ts
├─── dtos
│ {something}.dto.ts
├─── inputs
│ {something}.input.ts
├─── tests
│ {something}.spec.ts
│ {module-name}.module.ts
│ {module-name}.service.ts
│ {module-name}.resolver.ts
```### Entities (entities):
* Where you save all your entities;
* The entities are the classes that represent the [database tables](https://mikro-orm.io/docs/defining-entities)
and the [Graphql Object Types](https://docs.nestjs.com/graphql/resolvers#object-types);
* These are normally decorated with the [@Entity](https://mikro-orm.io/docs/defining-entities) decorator and the
[@ObjectType](https://docs.nestjs.com/graphql/resolvers#object-types) decorator;
* File Extension: {something}.entity.ts
* **Gql (gql):**
- Where you save the [Generic Graphql Object Types](https://docs.nestjs.com/graphql/resolvers#generics) (ex:
PaginatedUsers, etc.);
- These are normally decorated with the
[@ObjectType](https://docs.nestjs.com/graphql/resolvers#object-types) decorator;
- File Extension: {something}.type.ts### Interfaces (interfaces):
* Where you save all the interfaces and TypeScript types;
* File Extension: {something}.interface.ts### Enums (enums):
* Where you save all general enums and [Enum Type](https://docs.nestjs.com/graphql/unions-and-enums#code-first-1);
* File Extension: {something}.enum.ts### Dtos (dtos):
* Where you save all the DTOs (Data Transfer Objects) mainly for your Queries;
* These are normally decorated with
the [ArgsType](https://docs.nestjs.com/graphql/resolvers#dedicated-arguments-class) decorator;
* File Extension: {something}.dto.ts### Inputs (inputs):
* Where you save all the [GraphQL Input Objects](https://docs.nestjs.com/graphql/mutations#code-first) mainly for
your Mutations;
* These are normally decorated with
the [@InputType](https://docs.nestjs.com/graphql/mutations#code-first) decorator;
* File Extension: {something}.input.ts### Tests (tests):
* Where you save all the unit tests for your module's [services](https://docs.nestjs.com/providers#services),
[resolvers](https://docs.nestjs.com/graphql/resolvers) and [controllers](https://docs.nestjs.com/controllers);
* These are normally the spec files generated by the cli, but you still need to move them to this folder;
* File Extension: {something}.spec.ts### Optional Folders:
* **Embeddables (embeddables):**
- Where you save all your [JSON Fields](https://www.geeksforgeeks.org/postgresql-json-data-type/) for your
database tables;
- These are normally decorated with the [@Embeddable](https://mikro-orm.io/docs/embeddables) decorator;
- File Extension: {something}.embeddable.ts
* **Guards (guards):**
- Where you save all your [NestJS Guards](https://docs.nestjs.com/guards) related to your module;
- File Extension: {something}.guard.ts## Initial Set Up
### Installation
```bash
$ yarn install
```### Database Migrations
```bash
# creation
$ yarn migrate:create
# update
$ yarn migrate:update
```### Running the app
```bash
# production mode
$ yarn start# watch mode
$ yarn start:dev# debug mode
$ yarn start:debug
```## Local setup
1. Create a repo using this template;
2. Install the dependencies:```bash
$ yarn install
```3. Create a .env file with all the fields equal to the [example](.env.example).
4. Run the app in development mode:```bash
$ yarn start:dev
```## Unit Testing
### BEFORE EACH TEST (Individual or All):
* Check if NODE_ENV is not production;
* Remove the current test.db (if exits);
* Create a new test.db.```bash
# remove test.db
$ rm test.db
# create a new test.db
$ yarn migrate:create
```### All tests:
```bash
# unit tests
$ yarn run test --detectOpenHandles
```### Individual test:
```bash
# unit tests
$ yarn run test service-name.service.spec.ts --detectOpenHandles
```## Deployment
### Steps:
1. Go to [DigitalOcean](https://www.digitalocean.com/), [Linode](https://www.linode.com/)
or [Hetzner](https://www.hetzner.com/);
2. Create a server running [Ubuntu LTS](https://ubuntu.com/);
3. Install [dokku](https://dokku.com/docs~v0.28.1/getting-started/installation/#1-install-dokku);
4. Run the following commands on your server for dokku initial set-up:```bash
$ cat ~/.ssh/authorized_keys | dokku ssh-keys:add admin
$ dokku domains:set-global your-global-domain.com
```5. Create a new app and connect git:
```bash
$ dokku apps:create app-name
```6. Add the [Postgres plugin](https://github.com/dokku/dokku-postgres) to dokku, create a new PG instance and link it to
the app:```bash
$ sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres
$ dokku postgres:create app-name-db
$ dokku postgres:link app-name-db app-name
```7. Add the [Redis plugin](https://github.com/dokku/dokku-redis) to dokku, and create a new Redis instance and link it to
the app:```bash
$ sudo dokku plugin:install https://github.com/dokku/dokku-redis.git redis
$ dokku redis:create app-name-redis
$ dokku redis:link app-name-redis app-name
```8. Add all the other configurations as in the [example](.env.example) file:
```bash
$ dokku config:set app-name URL=https://your-domain.com ...
```9. On the project folder on your local computer run the following commands:
```bash
$ git remote add dokku dokku@server-public-ip-address:app-name
$ git push dokku main:master
```10. Finally set up SSL and a domain for your app:
```bash
$ sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
$ dokku config:set --global [email protected]
$ dokku domains:set app-name your-domain.com
$ dokku letsencrypt:enable app-name
$ dokku letsencrypt:cron-job --add
```## Support the frameworks used in this template
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If
you'd like to join them, please [read more here](https://docs.nestjs.com/support).Mikro-ORM is a TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. If you like
MikroORM, give it a [star](https://github.com/mikro-orm/mikro-orm) on GitHub and
consider [sponsoring](https://github.com/sponsors/B4nan) its development![Sharp](https://sharp.pixelplumbing.com/) is a high performance Node.js image processor. If you want
to [support them.](https://opencollective.com/libvips)## License
This template is [MIT licensed](LICENSE).