boilerplate-nexus-prisma-apollo-graphql-express
boilerplate-nexus-prisma-apollo-graphql-express copied to clipboard
Boilerplate project for a graphql server using nexus-prisma and apollo-server-express
✨ Boilerplate project for nexus-prisma apollo-express-graphql backend server
~~⚠️ Disclaimer: the project uses the prisma framework that is not ready for production yet. See
isprisma2ready.com.~~
Code written using nodejs version LTS
>= 12.x.x.
This project wants to be a starting point for more complex backend projects using graphql. Of his own, it manages the backend for a simple todo application but it handles important other topics besides the basic crud api for todos.
Getting started
The project uses nps (npm-package-scripts) so in the file package.json there are only 3 scripts, one for each main environment, and the scripts logic inside package-scripts.js:
"scripts": {
"dev": "cross-env NODE_ENV=development nps",
"prod": "cross-env NODE_ENV=production nps",
"test": "cross-env NODE_ENV=test nps"
},
npm i # install dependencies packages (there are a few 😧)
npm run <dev|test|prod> generate # generate prisma-client-js library and typescript definitions for nexus-prisma. Before doing it, set the environment variables needed
npm run dev # start development server
npm run test # start jest tests suite
npm run prod # generate, build and start the production server
npm run <dev|test|prod> prisma.migrate # create migration
npm run <dev|test|prod> prisma.migrate.up # apply migration
npm run <dev|test|prod> prisma.migrate.down # rollback migration
npm run dev generate.nexus # useful to generate only the nexus typescript definitions while implementing new features
Environment variables
Check file environment.example.env or test.example.env, then create for each environment the relative env file with the env var wanted.
config/development.env # for development
config/test.env # for test
config/production.env # for production
COOKIE_SECRETcookie secret for signed cookiesFRONTEND_URLSlist of urls separated by a comma for cors optionsJWT_SECRETjsonwebtoken secret for auth operationsJWT_TOKEN_EXPIRES_SEC_INamount of seconds that the generated jwt token will be validPORTserver port, default 4000DATABASE_URLdatabase (postgres) db access urlREDIS_HOSTredis db hostname, used for graphql subscriptionsREDIS_PASSWORDredis db passwordREDIS_PORTredis db port, default 6379WRITE_CUSTOM_LOG_TO_FILEyes/no, write log only to console or console and filesystem
Graphql server security
- express middlewares
- apollo-graphql
- validation rules (definitionLimit, depthLimit, fieldLimit): same logic from the keystonejs framework check here
- graphql-rate-limit
- graphql-shield 🛡️
- for query limiting: input field rules have been used. (first, last field)
~~Tests~~ (Broken [todo])
~~> ⚠️ with the latest versions the property enabled on datasource section on schema.prisma is no longer available and since the test environment changes the db source dynamically for every test cases, for the moment, it is not possible to run the test suite.~~ Although this feature is implemented (see here https://github.com/prisma/prisma/issues/1487) the test suite is still broken because it uses the sqlite provider with an enum for the roles but sqlite does not support enum types. It is needed to switch the test db provider to postgres.
Before run npm run test, set the config/test.env file and run npm run test prisma.migrate.up (check prisma docs to see the correct flow to follow). This command will set your sqlite db on /src/tests/db/data.sqlite. This db should not contain data and schema must be updated (run prisma.migrate.up in test env every time the schema.prisma is updated).
Each test suite will do (see testUtils.ts):
- a copy of the
data.sqliteinto the/src/tests/db/generatedfolder - start the backend server, the port is choosen using arbitrary-unused-port
- seed the copied db with 'dummy' data that test will use it.
- run tests
- clean test environment (close backend server, Prisma-Client connection and delete the copied sqlite db)
Todo
- [ ] test graphql subscriptions
- [ ] optimize tests flow (tests run need a lot of pc resources to bootstrap the server for each test suite and compilation from typescript)
- [ ] upload file endpoint (not needed but nice to have into the boilerplate project)
- [x] process manager in production (
npm run prodwill start the api withpm2in cluster mode) - [x] use some kind of autogenerated documentation tool system and publish it to
GET /of the backend server. Used https://github.com/2fd/graphdoc.
Other
The backend is ready to be used with CapRover, indeed captain-definition file exist on the root project (see also dockerfile).
One instance of the backend project is up and running on: https://nexus-prisma-boilerplate.epbe.dynu.net/graphql (auto-generated docs: https://nexus-prisma-boilerplate.epbe.dynu.net/). The
FRONTEND_URLSenv var is set tohttp://127.0.0.1:3000,http://localhost:3000so it is possible to play with the backend with a local frontend environment (likenextjs).