Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/stradivario/gapi-starter
Starter project based on @Gapi GraphQL scalable API
https://github.com/stradivario/gapi-starter
and easy enabled for gapi heroku project starter with workers
Last synced: 9 days ago
JSON representation
Starter project based on @Gapi GraphQL scalable API
- Host: GitHub
- URL: https://github.com/stradivario/gapi-starter
- Owner: Stradivario
- Created: 2018-03-04T14:20:34.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2020-07-11T20:11:28.000Z (over 4 years ago)
- Last Synced: 2024-12-07T17:27:17.896Z (2 months ago)
- Topics: and, easy, enabled, for, gapi, heroku, project, starter, with, workers
- Language: TypeScript
- Homepage:
- Size: 2.91 MB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# @Gapi Basic Starter
[![Build Status](https://travis-ci.org/Stradivario/gapi-starter.svg?branch=master)](https://travis-ci.org/Stradivario/gapi-starter)
## @Nginx, @Rabbitmq, @Postgres, @Sequelize, @Docker, @Graphql
## This is basic example project related with [GAPI](https://github.com/Stradivario/gapi)
## To check advanced example project go to [advanced-example](https://github.com/Stradivario/gapi-starter-postgres-sequelize-rabbitmq)
Heroku ready!
Just set environment variable for graphiql websocket protocol `GRAPHIQL_WS_PATH=your-app-name.herokuapp.com`
[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy)
Basic example has heroku ready button so global dependencies like ts-node and gapi-cli are installed inside project so Heroku builder will look inside node_modules.If you don't use heroku just write the following command:
```bash
npm uninstall @gapi/cli ts-node
```### To start developing clone repository
```bash
git clone https://github.com/Stradivario/gapi-starter
```#### Better use command line utility(gapi-cli) to install it type following command:
```bash
npm i -g @gapi/cli
```#### Type the following command to create new project from scratch via CLI
```bash
gapi new my-project
```#### To start project for "development" type:
```bash
npm start
```#### To start project for "production" type:
This will run following commands "pm2 process.yml --only APP" (DEVELPOMENT) or "pm2-docker process.yml --only APP"(PRODUCTION inside docker) (check process.yml inside root repository)
```bash
npm run start:prod
```#### To stop project for "production" type:
Following command will stop pm2 processes started
```bash
npm run stop:prod
```### Testing
#### To start developing with testing GAPI uses JEST and gapi-cli is preconfigurated for your needs! :)
#### To run single test type:
```bash
gapi test
```#### Testing watch mode
##### Note: You need to start server before running tests
###### Note: Everytime you make change to server it will restart server and execute tests
###### Note: To add more tests just create e2e.spec.ts or unit.spec.ts somewhere inside the application
##### Start the application
```bash
gapi start
```##### Execute test with --watch argument
```bash
gapi test --watch
```###### You will end up with something like this
![Alt Text](https://raw.githubusercontent.com/Stradivario/gapi-cli/master/docs/assets/images/sidebyside.png)
#### Custom logic before testing ( for example creating MOCK users to database before testing)
##### Create file test.ts inside root/src/test.ts with this content
##### Everytime you run test with --before argument it will set environment variable BEFORE_HOOK
```typescript
if (process.env.BEFORE_HOOK) {
// do something here
}
```##### Then execute tests with --before
```bash
gapi test --before
```###### This command will start root/src/test.ts file and will wait for process.exit(0) so you can customize your before logic check [this](https://github.com/Stradivario/gapi-starter-postgres-sequelize-rabbitmq/blob/master/src/test.ts#L73) link for reference
### Docker
#### Following commands will start RabbitMQ, PostgreSQL, API, NGINX as a services you need DOCKER for them
##### API will be served on https://localhost:80 and https://localhost:80/subscriptions
#### To build project with Docker type:
```bash
gapi app build
```#### To start project with Docker type:
```bash
gapi app start
```#### To stop project type:
```bash
gapi app stop
```### Workers
#### All workers will be mapped as Proxy and will be reverted to https://localhost:80 and https://localhost:80/subscriptions
##### So you don't have to worry about if some of your workers stopped responding
###### TODO: Create monitoring APP for all workers and main API
#### To start workers type
```bash
gapi workers start
```#### To stop workers type
```bash
gapi workers stop
```##### To add more workers
###### By default there are 4 workers with 4 processes with "exec_mode: cluster" of the original process inside single docker container
###### You can control Processes inside single docker container from "root/process.yml" file.
```yml
apps:
- script : './src/main.ts'
name : 'APP'
exec_mode: 'cluster'
instances: 4```
###### To map new worker as a stream open root/nginx/config/private/default
```nginx
upstream app_servers {
server 182.10.0.3:9000; # Main process
server 182.10.0.21:9000; # Worker 1
server 182.10.0.22:9000; # Worker 2
server 182.10.0.23:9000; # Worker 3
server 182.10.0.24:9000; # Worker 4# Add more workers here
# server 182.10.0.25:9000; # Worker 5
}server {
listen 80;
server_name api.yourdomain.com;
access_log api-yourdomain.access.log;location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
client_max_body_size 50M;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffering off;
proxy_buffer_size 16k;
proxy_read_timeout 600s;
proxy_pass http://app_servers;
}location /subscriptions {
# prevents 502 bad gateway error
proxy_buffers 8 32k;
proxy_buffer_size 64k;# redirect all HTTP traffic to localhost:9000;
proxy_pass http://app_servers/subscriptions;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-NginX-Proxy true;# enables WS support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
proxy_read_timeout 999999999;}
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
listen 443;
ssl on;
ssl_certificate /usr/share/certs/cert.pem;
ssl_certificate_key /usr/share/certs/cert.key;
}```
###### When you add another worker it should be on different IP with same port 9000
###### Open root/gapi.conf.yml file you will find this file:
```yml
config:
# Application configuration
app:
local:
API_PORT: 9000
API_CERT: ./cert.key
NODE_ENV: development
AMQP_HOST: 182.10.0.5
AMQP_PORT: 5672
GRAPHIQL: true
GRAPHIQL_TOKEN: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImtyaXN0aXFuLnRhY2hldkBnbWFpbC5jb20iLCJpZCI6MSwic2NvcGUiOlsiQURNSU4iXSwiaWF0IjoxNTIwMjkxMzkyfQ.9hpIDPkSiGvjTmUEyg_R_izW-ra2RzzLbe3Uh3IFsZg
ENDPOINT_TESTING: http://localhost:9000/graphql
TOKEN_TESTING: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImtyaXN0aXFuLnRhY2hldkBnbWFpbC5jb20iLCJzY29wZSI6WyJBRE1JTiJdLCJpZCI6MSwiaWF0IjoxNTE2OTk2MzYxfQ.7ANr5VHrViD3NkCaDr0nSWYwk46UAEbOwB52pqye4AM
prod:
API_PORT: 9000
API_CERT: ./cert.key
NODE_ENV: production
AMQP_HOST: 182.10.0.5
AMQP_PORT: 5672
# Testing configuration for local(dev) or worker(running tests as a separate worker with separate environment)
test:
local: extends app/local
worker:
API_PORT: 9000
API_CERT: ./cert.key
NODE_ENV: production
AMQP_HOST: 182.10.0.5
AMQP_PORT: 5672
ENDPOINT_TESTING: http://182.10.0.101:9000/graphql
TOKEN_TESTING: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImtyaXN0aXFuLnRhY2hldkBnbWFpbC5jb20iLCJzY29wZSI6WyJBRE1JTiJdLCJpZCI6MSwiaWF0IjoxNTE2OTk2MzYxfQ.7ANr5VHrViD3NkCaDr0nSWYwk46UAEbOwB52pqye4AMschema:
introspectionEndpoint: http://localhost:9000/graphql
introspectionOutputFolder: ./src/app/core/api-introspectioncommands:
testing:
stop:
- docker rm -f gapi-api-prod-worker-tests-executor
- docker rm -f gapi-api-prod-worker-tests-provider
start:
- gapi testing start-provider
- sleep 10
- gapi testing start-executor
- echo Cleaning...
- gapi testing stop
start-provider: docker run -d --network=gapiapiprod_gapi --ip=182.10.0.101 --name gapi-api-prod-worker-tests-provider gapi/api/prod
start-executor:
- docker run -d --network=gapiapiprod_gapi --ip=182.10.0.100 --name gapi-api-prod-worker-tests-executor gapi/api/prod
- docker exec gapi-api-prod-worker-tests-provider npm -v
- gapi test --worker --beforeworkers:
start:
- gapi workers start-1
- gapi workers start-2
- gapi workers start-3
- gapi workers start-4
stop:
- docker rm -f gapi-api-prod-worker-1
- docker rm -f gapi-api-prod-worker-2
- docker rm -f gapi-api-prod-worker-3
- docker rm -f gapi-api-prod-worker-4
start-1: docker run -d --network=gapiapiprod_gapi --ip=182.10.0.21 --name gapi-api-prod-worker-1 gapi/api/prod
start-2: docker run -d --network=gapiapiprod_gapi --ip=182.10.0.22 --name gapi-api-prod-worker-2 gapi/api/prod
start-3: docker run -d --network=gapiapiprod_gapi --ip=182.10.0.23 --name gapi-api-prod-worker-3 gapi/api/prod
start-4: docker run -d --network=gapiapiprod_gapi --ip=182.10.0.24 --name gapi-api-prod-worker-4 gapi/api/prod
example-worker-with-port: docker run -d --network=gapiapiprod_gapi --ip=182.10.0.25 --name gapi-api-prod-worker-5 -p 9001:9000 gapi/api/prodapp:
start:
- docker-compose -p gapi-api-prod up --force-recreate -d
- gapi rabbitmq enable-dashboard
stop:
- gapi nginx stop
- gapi api stop
- gapi rabbitmq stop
- gapi postgres stop
build: docker build -t gapi/api/prod .api:
stop: docker rm -f gapi-api-prodnginx:
stop: docker rm -f gapi-api-nginxpostgres:
stop: docker rm -f gapi-api-postgresrabbitmq:
stop: docker rm -f gapi-api-rabbitmq
restart: docker restart gapi-api-rabbitmq
enable-dashboard: docker exec gapi-api-rabbitmq rabbitmq-plugins enable rabbitmq_management# You can define your custom commands for example
# commands:
# your-cli:
# my-command: 'npm -v'
# This command can be executed as "gapi your-cli my-command"
```###### Adding one more worker:
```yml
start-5: 'docker run -d --network=gapiapiprod_gapi --ip=182.10.0.25 --name gapi-api-prod-worker-5 -p 9005:9000 gapi/api/prod'
```###### Then edit start task inside workers to start new worker 5
```yml
start: 'gapi workers start-1 && gapi workers start-2 && gapi workers start-3 && gapi workers start-4 & gapi workers start-5'
```###### Thats' it!! Now you have 4 processes like CLUSTERS inside 1 docker container with ip 182.10.0.25 and external port(optional) 9005;
###### You can specify worker also without port because all workers are inside internal network called "gapiapiprod_gapi"
###### 182.10.0.21/22/23/24/25:9000
```yml
start-5: 'docker run -d --network=gapiapiprod_gapi --ip=182.10.0.25 --name gapi-api-prod-worker-5 gapi/api/prod'
```###### If you want to change port forwarding to another port you need to set just nginx configuration:
```yml
nginx:
image: sameersbn/nginx:1.10.1-5
ports:
- "81:80"
- "443:443"
```###### Now you can find your API served onto https://localhost:81/ and https://localhost:81/subscriptions
###### All workers don't care about that because they will be served and mapped from nginx to port 80
###### You can check docker-compose file to configurate environment variables
```yml
version: '2'
services:nginx:
image: sameersbn/nginx:1.10.1-5
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/config:/etc/nginx
- ./nginx/html:/usr/share/nginx/html/
- ./nginx/certs:/usr/share/certs
restart: always
container_name: gapi-api-nginx
networks:
gapi:
ipv4_address: 182.10.0.2api:
image: gapi/api/prod:latest
ports:
- "9000"
restart: always
mem_limit: 1000000000
cpu_shares: 73
container_name: gapi-api-prod
depends_on:
- nginx
- rabbitMq
networks:
gapi:
ipv4_address: 182.10.0.3rabbitMq:
image: rabbitmq:3.7.2
ports:
- "15672:15672"
- "5672:5672"
- "5671:5671"
- "4369:4369"
restart: always
container_name: gapi-api-rabbitmq
networks:
gapi:
ipv4_address: 182.10.0.5networks:
gapi:
driver: bridge
ipam:
config:
- subnet: 182.10.0.0/16
gateway: 182.10.0.1```
##### After successfully started project you can open your browser to localhost:80 or 182.10.0.3:9000 the api will be served there
TODO: Better documentation...
Enjoy ! :)