Awesome
express-graphql-typescript-boilerplate
A GraphQL starter kit for building amazing API's in TypeScript and with Express.js framework.
This seed repository has a complete GraphQL starter kit written in TypeSciprt. For building our API we use various gulp-tasks. We use jasmine and Wallaby for our unit-testing. And there are a lot more awesome features like
- VSCode tasks and launch configuration
- Improved GraphQL Error Handling, so that the error stack will be shown in the console
- Multiple environemnt configurations
- Basic security configuration
- Basic cors configuration
- Basic logger configuration
- Advanced GraphQL-Context logic, so we can use repos, dataloader and other stuff in each resolver
- Complete Knex.js integration with seeders and migration
- DataLoaders
- Extended GraphQL-Query and GraphQL-Field with a lite Hook-System
- A lot of examples like:
- Pagination
- Search query with filter
- Custom GraphQL-Types like a date type
- Migtation and seeders
- Models
- Testing examples
- and many more, just have a look
Getting Started
Prerequisites
Install Node.js
- on OSX use homebrew
brew install node
- on Windows use chocolatey
choco install nodejs
Installing
fork
this repoclone
your forknpm install
to install all dependenciesnpm run install:typings
to install all typings- Create new database. You will find the name in the
src/config.ts
file. npm run db:migrate
to create the schemanpm run db:seed
to insert some test datanpm run serve
to start the dev server in another tab
Running the app
After you have installed all dependencies you can now run the app.
Run npm run serve
to start a local server using nodemon
which will watch for changes and then will restart the sever.
The port will be displayed to you as http://0.0.0.0:3000
(or if you prefer IPv6, if you're using express
server, then it's http://[::1]:3000/
).
Scripts / Commands
Install
- Install all dependencies with
npm install
- Install all typings with
npm run install:typings
- To install all dependencies and typings use
npm run install:dev
- Remove not needed libraries with
npm run install:clean
Linting
- Run code analysis using
npm run lint
. This runs tshint. - There is also a vscode task for this called lint.
Tests
- Run the unit tests using
npm test
ornpm run test:pretty
for more detailed reporting. - There is also a vscode task for this called test.
Running in dev mode
- Run
npm run serve
to start nodemon with ts-node, which will serve your app. - The server address will be displayed to you as
http://0.0.0.0:3000
Cleaning the project
- Run
npm run clean
to remove all generated JavaScript files.
Building the project and run it
- Run
npm run build
to generated all JavaScript files from your TypeScript sources. After this step you can deploy the app on any server. - There is also a vscode task for this called build.
- To start the builded app use
npm start
. - With
npm run zip
it will generate the JavaScript source and pack them into to a deployable zip file into the dist folder.
Docs
- Run
npm run docs
to generate all doc files and serve it onhttp://0.0.0.0:8080
Seed
- Run
npm run db:seed
to seed some data into the database
Migration
- Run
npm run db:migrate
to migration the new schema to the database - Run
npm run db:migrate:rollback
to rollback one version
Exploring the boilerplate
Structure
express-graphql-typescript-boilerplate
|-- .vscode/ * our vscode tasks, launch configuration and some settings
|-- build/ * our task runner configurations and tasks
| |-- tasks/ * gulp tasks
| |-- paths.js * project path setup for our gulp tasks
| |-- util.js * our gulp helper functions
|
|-- docs/ * our generated doc files
|
|-- src/ * our source files that will be compiled to javascript
| |
| |-- context/ * graphql context
| | |-- Context.ts * our graphql context class
| | |-- DataloadersContext.ts * our collection of all dataloaders
| | |-- ServicesContext.ts * our collection of all repositories
| |
| |-- core/ * our core functionalities
| | |-- Bootstrap.ts * our express helper functions to init and run the server
| | |-- Database.ts * our database setup
| | |-- Environment.ts * gets us the configuration for the given environment
| | |-- GraphQLErrorHandling.ts * our error handling
| | |-- Logger.ts * our logger configurations
| | |-- Server.ts * our server error handling
| | |-- Tables.ts * our database table names
| | |-- Utils.ts * our collection of util functions
| |
| |-- database/ * our database tasks
| | |-- factories * our factories to create simple fake data
| | |-- migrations * our database migration tasks
| | |-- seeds * our database seeder tasks
| |
| |-- exceptions/ * our errors to throw to the user
| | |-- Exception.ts * our basic user error all other errors should inherit from this one
| | |-- NotFoundException.ts * a basic not found error
| |
| |-- middlewares/ * our express custom middlewares (/*.middleware.ts)
| |
| |-- models/ * our database models (/*.model.ts)
| |
| |-- repositories/ * use a repository to fetch the date of the database
| | |-- **/*Repository.ts
| |
| |-- services/ * use a services to separate the logic that retrieves the data and maps it to the entity model from the business logic that acts on the model
| | |-- **/*Services.ts
| |
| |-- routes/ * defines our application routes
| | |-- **/*Routes.ts
| |
| |-- schemas/ * our graphql schema definitions (use a single file for every graphql object action)
| | |-- arguments/ * our graphql argument files
| | |-- fields/ * our graphql field files
| | |-- mutations/ * our graphql mutation files
| | |-- queries/ * our graphql query files
| | |-- types/ * our graphql type files
| |
| |-- index.ts * main entry point for our application
| |-- RootValue.ts * RootValue with some functions for all the queries and mutations
| |-- config.ts * has our configuration for our different environments
|
|-- test/ * our test files that will test our application
| |-- mocks * we use this to simulate other functions, classes or objects
| |-- unit/**/*.spec.ts * our unit test cases
|
|-- typings_custom/ * our local type definitions
|
|-- knexfile.ts * this has our database configuration from the config.ts
|-- gulpfile.js * entry point for our gulp tasks
|-- nodemon.json * nodemon setup, so that it uses typescript and runs tslint
|-- package.json * what npm uses to manage it's dependencies
|-- tslint.json * typescript lint config
|-- typedoc.json * typescript documentation generator
|-- tsconfig.json * typescript config
|-- wallaby.js * our wallaby configuration
Hook-System
// We extend the AbstractQuery with the hook system. This
// gives us the 3 new methods called before, run and after.
export class FindAllBooksQuery extends AbstractQuery implements GraphQLFieldConfig {
public type = new GraphQLList(BookType);
public allow = ['admin'];
public args = {
limit: new LimitArgument(),
offset: new OffsetArgument()
};
// This will be called after the allow checking
public before(context: Context, args: common.PageinationArguments): Promise<common.PageinationArguments> {
log.debug('hook before args', args);
LimitArgument.validate(args.limit);
OffsetArgument.validate(args.limit);
return Promise.resolve(args);
}
// As long as the before function was okay this will be called afterwards
public execute(root: RootValue, args: common.PageinationArguments, context: Context): Promise<models.book.Attributes> {
log.debug('resolve findAllBooks()');
return context.Repositories.BookRepository.findAllBooks({
limit: args.limit,
offset: args.offset
});
}
// And at least before the results go back to our client it will pass this after function
public after(result: models.book.Attributes, context: Context, args: common.PageinationArguments): Promise<models.book.Attributes> {
log.debug('hook after args', args);
return Promise.resolve(result);
}
}
Related Projects
- GraphQL.js — The JavaScript reference implementation for GraphQL
- DataLoader — Batching and caching for GraphQL data access layer
- aurelia-typescript-boilerplate - An Aurelia starter kit with TypeScript
- express-typescript-boilerplate - Boilerplate for an restful express-apllication written in TypeScript
License
Made with ♥ by Gery Hirschfeld (@GeryHirschfeld1) and contributors