Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[express-apollo-prisma] Final cleanup from demo feedback #1207

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions starters/express-apollo-prisma/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ indent_size = 2
[*.md]
max_line_length = off
trim_trailing_whitespace = false

[{package.json, eslintrc.json}]
indent_style = space
40 changes: 19 additions & 21 deletions starters/express-apollo-prisma/.env.example
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
# Application
PORT=4001
DATABASE_URL="mysql://root:root@localhost:3307/testdb"
REDIS_URL="redis://:redi$pass@localhost:6380"
CORS_ALLOWED_ORIGINS= # optional. Default value: '*'. Sample value: CORS_ALLOWED_ORIGINS=https://starter.dev,http://127.0.0.1

# MySQL
DB_USER=demo
DB_PASSWORD=demopass
DB_DATABASE=demodb
DB_PORT=3306
DB_URL="mysql://root:${DB_PASSWORD}@localhost:${DB_PORT}/${DB_DATABASE}"

# Redis
REDIS_PASSWORD='redi$pass' # important! Quotes are required when using special characters
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_CACHE_TTL_SECONDS=1800
# For docker-compose.yaml
# mysql
DOCKER_MYSQLDB_ROOT_PASSWORD=root
DOCKER_MYSQLDB_DATABASE=testdb
DOCKER_MYSQLDB_PORT_LOCAL=3307
DOCKER_MYSQLDB_PORT_CONTAINER=3306
# redis
DOCKER_REDIS_PASSWORD='redi$pass' # important! single quotes required
DOCKER_REDIS_HOST=localhost
DOCKER_REDIS_PORT_LOCAL=6380
DOCKER_REDIS_PORT_CONTAINER=6379
# rabbitmq

# RabbitMQ
AMQP_URL=amqp://localhost:5673
AMQP_QUEUE_JOB="jobs"
DOCKER_RABBIT_MQ_PORT_CLIENT_API_LOCAL=5673
DOCKER_RABBIT_MQ_PORT_CLIENT_API_CONTAINER=5672
DOCKER_RABBIT_MQ_PORT_ADMIN_API_LOCAL=15673
DOCKER_RABBIT_MQ_PORT_ADMIN_API_CONTAINER=15672
# cors
CORS_ALLOWED_ORIGINS= # optional. Default value: '*'. Sample value: CORS_ALLOWED_ORIGINS=https://starter.dev,http://127.0.0.1
AMQP_QUEUE_JOB=jobs
RABBIT_MQ_PORT_CLIENT=5673
RABBIT_MQ_PORT_ADMIN=15673
84 changes: 66 additions & 18 deletions starters/express-apollo-prisma/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ This starter kit features Express, Apollo Server and Prisma.
- [Express](#express)
- [Apollo Server](#apollo-server)
- [ORM](#orm)
- [How to use kit with MongoDB](#how-to-use-kit-with-mongodb)
- [Queueing](#queueing)
- [Caching](#caching)
- [Testing](#testing)
- [Deployment](#deployment)
- [Build a Production Scale app with Express-Apollo-Prisma kit](#build-a-production-scale-app-with-express-apollo-prisma-kit)

## Overview

Expand Down Expand Up @@ -106,27 +108,20 @@ git clone https://github.com/thisdot/starter.dev.git
## Environment Variables

- `PORT` - The port exposed to connect with the application.
- `DATABASE_URL` - The database connection URL.
- `REDIS_URL` - The Redis connection URL.
- `DB_URL` - Connector for Prisma to run the migrations (our example will build the correct URL from the other variables)
- `DB_USER` - User to use on the MySQL server
- `DB_PASS` - Password for both the user and root user
- `DB_DATABASE` - Name of the database in MySQL
- `DB_PORT` - Which port to run the MySQL server on
- `REDIS_USER` - User to use on the Redis server (can be left blank)
- `REDIS_PASSWORD` - Password to authenticate Redis
- `REDIS_HOST` - Host Redis is running on
- `REDIS_PORT` - Which port to run the Redis server on
- `REDIS_CACHE_TTL_SECONDS` - The remaining time(seconds) to live of a key that has a timeout.
- `DOCKER_MYSQLDB_ROOT_PASSWORD` - The MySQL root user password.
- `DOCKER_MYSQLDB_DATABASE` - The MySQL database name.
- `DOCKER_MYSQLDB_PORT_LOCAL` - The MySQL Docker host's TCP port.
- `DOCKER_MYSQLDB_PORT_CONTAINER` - The MySQL Docker container's TCP port.
- `DOCKER_REDIS_PASSWORD` - The Redis password.
- `DOCKER_REDIS_HOST` - The Redis host IP.
- `DOCKER_REDIS_PORT_LOCAL` - The Redis Docker host's TCP port.
- `DOCKER_REDIS_PORT_CONTAINER` - The Redis Docker container's TCP port.
- `AMQP_URL` - The RabbitMQ connection URL.
- `AMQP_QUEUE_JOB` - The RabbitMQ channel queue name.
- `CORS_ALLOWED_ORIGINS` - (Optional) Comma separated Allowed Origins. Default value: '\*'. (See [CORS Cross-Origin Resource Sharing](#cors-cross-origin-resource-sharing))

We map TCP port `DOCKER_MYSQLDB_PORT_CONTAINER` in the container to port `DOCKER_MYSQLDB_PORT_LOCAL` on the Docker host.
We also map TCP port `DOCKER_REDIS_PORT_LOCAL` in the container to port `DOCKER_REDIS_PORT_CONTAINER` on the Docker host.

To ensure proper connection to our resources
For more information on Docker container networks: https://docs.docker.com/config/containers/container-networking/

### Database and Redis

To start up your API in development mode with an active database connection, please follow the following steps:
Expand Down Expand Up @@ -239,7 +234,7 @@ There is a `technologies` query in `technology.typedefs.ts` file. The query uses
type Query {
...
"Returns a list of Technologies"
technologies(limit: Int = 5, offset: Int = 0): TechnologyCollectionPage!
technologies(limit: Int = 5, offset: Int = 0): TechnologyCollection!
}
...
```
Expand Down Expand Up @@ -298,7 +293,7 @@ The data sources are located in `src/graphql/data-sources`. The data sources of

### ORM

The kit uses Prisma as a TypeScript ORM for proper data fetch and mutation from the source. It is configured with the following environment variable: `DATABASE_URL="mysql://root:root@localhost:3307/testdb"`.
The kit uses Prisma as a TypeScript ORM for proper data fetch and mutation from the source. It is configured with the `DB_URL` environment variable.

We use Prisma for the following:

Expand All @@ -307,6 +302,55 @@ We use Prisma for the following:

Learn more about [Prisma](https://www.prisma.io/docs/concepts/overview/prisma-in-your-stack/is-prisma-an-orm).

#### How to use kit with MongoDB

1. Set up a MongoDB account via the following tutorial: [Create MongoDB Account](https://www.mongodb.com/docs/guides/atlas/account/).
2. Set up MongoDB cluster. [Create Cluster](https://www.mongodb.com/docs/guides/atlas/cluster/)
3. Set up MongoDB User. [Create User](https://www.mongodb.com/docs/guides/atlas/db-user/)
4. Get the [MongoDB Connection URI](https://www.mongodb.com/docs/guides/atlas/connection-string/).
5. Replace the `<user>`, `<password>` and `<database>` to your `DB_URL` in your `.env` with the username, password and database you created.
```
DB_URL="mongodb+srv://<username>:<password>@app.random.mongodb.net/database?retryWrites=true&w=majority"
```
6. Replace the `DB_USER`, `DB_PASSWORD` and `DB_DATABASE` in your `.env` with the username, password and database you created.
7. Edit the datasource in `prisma/schema.prisma`.

```prisma
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}
```

8. Edit the `PRISMA_CONFIG` in `src/config.ts` to:

```ts
export const PRISMA_CONFIG: Prisma.PrismaClientOptions = {
datasources: {
db: {
url: `mongodb+srv://${DB_USER}:${DB_PASSWORD}@app.random.mongodb.net/${DB_DATABASE}?retryWrites=true&w=majority`,
},
},
};
```

9. Finally update your `src/healthcheck/datasource-healthcheck.ts` to check the mongodb connection.

```ts
import { PrismaClient } from '@prisma/client';

export const getDataSourceHealth = async (prismaClient?: PrismaClient) => {
try {
const prismaClientPingResult = await prismaClient?.$runCommandRaw({
ping: 1,
});
return prismaClientPingResult?.ok == 1;
} catch {
return false;
}
};
```

### Queueing

The kit provides an implementation of queueing using RabbitMQ, an open-source message broker that allows multiple applications or services to communicate with each other through queues. It's a powerful tool for handling tasks asynchronously and distributing workloads across multiple machines.
Expand Down Expand Up @@ -364,3 +408,7 @@ npm run infrastructure:up
3. Deploy your application to your chosen provider or service using their deployment tools or services. You can use the start script to start your application in production mode. You may also need to configure any necessary proxy or routing rules to direct incoming traffic to your application.

4. Monitor your application for any issues or errors and adjust your deployment as needed. This may involve configuring load balancers, auto-scaling, or other performance optimization features, depending on your chosen provider or service.

## Build a Production Scale app with Express-Apollo-Prisma kit

Learn how to build a Production Scale app with Express-Apollo-Prisma kit in this [article](https://www.thisdot.co/blog/building-a-production-scale-app-with-the-express-apollo-prisma-starter-kit). We will cover what's included in the kit, how to set it up, and how to use the provided tools to create a scalable web application. We will also discuss how to extend the starter kit to add features like authentication. Finally, we will look at how to use the provided tools to ensure that your application is well-maintained and efficient
35 changes: 13 additions & 22 deletions starters/express-apollo-prisma/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,36 @@ version: '3.8'

services:
mysql:
container_name: mysql
image: mysql:8.0
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=$DOCKER_MYSQLDB_ROOT_PASSWORD
- MYSQL_DATABASE=$DOCKER_MYSQLDB_DATABASE
- MYSQL_PASSWORD=${DB_PASSWORD:-demopass}
- MYSQL_USER=${DB_USER:-demo}
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD:-demopass}
- MYSQL_DATABASE=${DB_DATABASE:-demodb}
ports:
- $DOCKER_MYSQLDB_PORT_LOCAL:$DOCKER_MYSQLDB_PORT_CONTAINER
- '${DB_PORT:-3306}:3306'
volumes:
- db:/var/lib/mysql

redis:
container_name: redis
image: 'redis:7.0-alpine'
image: redis:7.0-alpine
restart: unless-stopped
env_file: ./.env
command:
- --loglevel warning
- --requirepass "$DOCKER_REDIS_PASSWORD"
- --requirepass ${REDIS_PASSWORD:-redi$$pass}
ports:
- $DOCKER_REDIS_PORT_LOCAL:$DOCKER_REDIS_PORT_CONTAINER
environment:
- REDIS_REPLICATION_MODE=master
depends_on:
- mysql
- '${REDIS_PORT:-6379}:6379'

rabbitmq:
image: rabbitmq:3.8-management-alpine
container_name: 'rabbitmq'
restart: unless-stopped
ports:
- $DOCKER_RABBIT_MQ_PORT_CLIENT_API_LOCAL:$DOCKER_RABBIT_MQ_PORT_CLIENT_API_CONTAINER
- $DOCKER_RABBIT_MQ_PORT_ADMIN_API_LOCAL:$DOCKER_RABBIT_MQ_PORT_ADMIN_API_CONTAINER
- '${RABBIT_MQ_PORT_CLIENT:-5672}:5672'
- '${RABBIT_MQ_PORT_ADMIN:-15672}:15672'
volumes:
- queue:/var/lib/rabbitmq/
- ./.docker-conf/rabbitmq/log/:/var/log/rabbitmq
networks:
- rabbitmq_nodejs
networks:
rabbitmq_nodejs:
driver: bridge

volumes:
db:
queue:
2 changes: 2 additions & 0 deletions starters/express-apollo-prisma/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export default {
'<rootDir>/graphql/schema/generated',
'index.ts',
'<rootDir>/mocks',
'<rootDir>/config.ts',
'<rootDir>/queue/worker.ts',
'\\.(d.ts)$',
],

Expand Down
7 changes: 3 additions & 4 deletions starters/express-apollo-prisma/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
"scripts": {
"codegen": "graphql-codegen && npm run format:codegen",
"prepare": "npm run prisma:generate && npm run codegen",
"test": "npm run prepare && jest",
"test": "jest",
"start": "npm run prepare && prisma migrate dev && nodemon",
"dev:test": "jest",
"dev:start": "nodemon",
"dev": "nodemon",
"build": "npm run prepare && tsc --project tsconfig.build.json",
"lint": "eslint \"src/**/*.ts\"",
"lint:fix": "npm run lint --fix",
Expand All @@ -31,7 +30,7 @@
"infrastructure:up": "docker compose up -d",
"infrastructure:pause": "docker compose stop",
"infrastructure:down": "docker compose down --remove-orphans --volumes",
"queue:run": "ts-node queue/worker.ts"
"queue:run": "ts-node src/queue/worker.ts"
},
"author": "",
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion starters/express-apollo-prisma/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ generator client {

datasource db {
provider = "mysql"
url = env("DATABASE_URL")
url = env("DB_URL")
}

model TechnologyEntity {
Expand Down
Loading