linedu-covid-support-1 linedu-plugins linedu-logo linedu-text Twake THE OPEN DIGITAL WORKPLACE Twake Secure opensource collaboration platform that
improves your organizational productivity
TRY IT FREE AT TWAKE.APP logo-twake
linshare-mobile Secure open source
file sharing app
Download LinShare app for Android and iOS linshare-download linshare-logo-linagora-vn
Linh Thao Nguyen

GraphQL + Clean Architecture boilerplate

Inspiration

The Clean Architecture is an awesome guide for developers who desire to build clean, structured, and maintainable projects. The letter L in the SOLID principle allows us to make dependent components are easily replaced without touch to the business and the core of systems. For an example of the web server where there are many frameworks out there (Expressjs, GraphQL, etc) and the chosen decision depends on the purpose of the business and the context.

In this boilerplate guide scope, we will go through how to make the core business immune to the change of the detailed technologies. Let’s go!

You can find the implementation detail in this repository

Boilerplate

.
├── package.json
├── package-lock.json
├── README.md
├── src
│   ├── application
│   │   ├── auth
│   │   │   └── index.ts
│   │   ├── graphql
│   │   │   ├── index.ts
│   │   │   ├── schemaShards
│   │   │   │   ├── index.ts
│   │   │   │   └── users.ts
│   │   │   ├── subscriptionManager.ts
│   │   │   └── utils
│   │   │       └── mergeRawSchemas.ts
│   │   └── index.ts
│   ├── dto
│   │   └── user.dto.ts
│   ├── entities
│   │   └── user.entity.ts
│   ├── index.ts
│   ├── IoC
│   │   ├── container.ts
│   │   ├── icradle.interface.ts
│   │   └── providers
│   │       ├── auth.provider.ts
│   │       └── user.provider.ts
│   ├── persistence
│   │   ├── auth.repository.ts
│   │   ├── constants.ts
│   │   ├── password.ts
│   │   └── user.repository.ts
│   ├── services
│   │   ├── auth.repository.interface.ts
│   │   ├── auth.service.ts
│   │   ├── user.repository.interface.ts
│   │   └── user.service.ts
│   └── __typedefs
│       ├── graphqlTypes.d.ts
│       └── schema.graphql
└── tsconfig.json

The main folder is `src` where contains the implementation:

– **application**: Application layer where we can use a backend web application framework. In this boilerplate is `GraphQL`

– **service**: The business service layer where we defined the logic to handle application use cases. This layer also contains adapters that abstract the detailed actions, for example, access to the database.

– **entities**: This is the core component of the application where we define the application entities.

– **persistence**: This is another detailed layer where we specify actions to communicate to the database, message queue, etc.

– **dto**: (stand for Data Transfer Object) defines communication contracts between layers. For example, what type of input params or return value that is used in methods of layers

– **IoC**: (stand for Inversion of Control) is an implementation of the Dependency Injection, the letter D in the SOLID principal. Every time you create a new Service class, or a new repository class, or a new controller, you need to register them in this container. This boilerplate uses Awilix library to achieve the factor.

The communication policies between layers and domains compliant with the Clean Architecture. The directions of arrows in the following diagrams show the relationship between components. For example, if an arrow direction from component X to component Y, it means component X depends on component Y.

  1. Dependency diagram

Dependency diagram

As you can see in the diagram the dependency flow among layers:

– Entity is the core layer and does not depend on any component

– To inverse the dependency from the domain business layer to the repository layer, there is a repository interface in the domain business. This allows us to be able to implement and update this layer with the detailed technologies

– Application Controller depends on the services

– IoC container depends on services, repositories, and application controllers because we need to register all of them to the container

– Application router depends on the IoC container that allows us to use registered application controllers to handle client requests

2. Dependency between domains

Dependency between domains diagram

In real-life projects, of course, there is not merely 1 domain. So, we need to define the communication rules between layers of them.

Getting Started

There are some beginning available command lines is defined the `scripts` part of the `package.json` file.

1. Install dependencies

npm i

2. Run the application under the `dev` mode with the hot reload feature

npm run dev

3. Compile the application

npm run build

4. Run the application under the `production` mode. You need to compile the application before

npm run start

5. Generate types for GraphQL schema. This action must be done each time you update the GraphQL schema to allow the typescript compiler to understand your schema:

npm run generate-typedefs

Author: LE CONG TUAN – TECHNICAL LEADER

The article was published on his blog on Medium, see more at https://congtuanle.medium.com/graphql-clean-architectire-boilerplate-1beb07935b41 

References