{"id":15456139,"url":"https://github.com/stradivario/gapi-starter","last_synced_at":"2025-10-15T18:21:42.223Z","repository":{"id":93607896,"uuid":"123795832","full_name":"Stradivario/gapi-starter","owner":"Stradivario","description":"Starter project based on @Gapi GraphQL scalable API","archived":false,"fork":false,"pushed_at":"2020-07-11T20:11:28.000Z","size":3052,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-25T08:39:40.507Z","etag":null,"topics":["and","easy","enabled","for","gapi","heroku","project","starter","with","workers"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Stradivario.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-04T14:20:34.000Z","updated_at":"2020-07-11T20:11:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"de135c6f-7653-4815-ad89-cabc13f8fbea","html_url":"https://github.com/Stradivario/gapi-starter","commit_stats":{"total_commits":429,"total_committers":1,"mean_commits":429.0,"dds":0.0,"last_synced_commit":"8a2842c261b2fa97163d0793debf748c7b16dbd5"},"previous_names":[],"tags_count":553,"template":false,"template_full_name":null,"purl":"pkg:github/Stradivario/gapi-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stradivario%2Fgapi-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stradivario%2Fgapi-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stradivario%2Fgapi-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stradivario%2Fgapi-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Stradivario","download_url":"https://codeload.github.com/Stradivario/gapi-starter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stradivario%2Fgapi-starter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268026443,"owners_count":24183431,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-31T02:00:08.723Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["and","easy","enabled","for","gapi","heroku","project","starter","with","workers"],"created_at":"2024-10-01T22:22:55.345Z","updated_at":"2025-10-15T18:21:37.189Z","avatar_url":"https://github.com/Stradivario.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @Gapi Basic Starter\n\n[![Build Status](https://travis-ci.org/Stradivario/gapi-starter.svg?branch=master)](https://travis-ci.org/Stradivario/gapi-starter)\n\n## @Nginx, @Rabbitmq, @Postgres, @Sequelize, @Docker, @Graphql\n\n## This is basic example project related with [GAPI](https://github.com/Stradivario/gapi)\n\n## To check advanced example project go to [advanced-example](https://github.com/Stradivario/gapi-starter-postgres-sequelize-rabbitmq)\n\nHeroku ready!\n\nJust set environment variable for graphiql websocket protocol `GRAPHIQL_WS_PATH=your-app-name.herokuapp.com`\n\n[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy)\n\nBasic 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:\n\n```bash\nnpm uninstall @gapi/cli ts-node\n```\n\n### To start developing clone repository\n\n```bash\ngit clone https://github.com/Stradivario/gapi-starter\n```\n\n#### Better use command line utility(gapi-cli) to install it type following command:\n\n```bash\nnpm i -g @gapi/cli\n```\n\n#### Type the following command to create new project from scratch via CLI\n\n```bash\ngapi new my-project\n```\n\n#### To start project for \"development\" type:\n\n```bash\nnpm start\n```\n\n#### To start project for \"production\" type:\n\nThis 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)\n\n```bash\nnpm run start:prod\n```\n\n#### To stop project for \"production\" type:\n\nFollowing command will stop pm2 processes started\n\n```bash\nnpm run stop:prod\n```\n\n### Testing\n\n#### To start developing with testing GAPI uses JEST and gapi-cli is preconfigurated for your needs! :)\n\n#### To run single test type:\n\n```bash\ngapi test\n```\n\n#### Testing watch mode\n\n##### Note: You need to start server before running tests\n\n###### Note: Everytime you make change to server it will restart server and execute tests\n\n###### Note: To add more tests just create e2e.spec.ts or unit.spec.ts somewhere inside the application\n\n##### Start the application\n\n```bash\ngapi start\n```\n\n##### Execute test with --watch argument\n\n```bash\ngapi test --watch\n```\n\n###### You will end up with something like this\n\n ![Alt Text](https://raw.githubusercontent.com/Stradivario/gapi-cli/master/docs/assets/images/sidebyside.png)\n\n#### Custom logic before testing ( for example creating MOCK users to database before testing)\n\n##### Create file test.ts inside root/src/test.ts with this content\n\n##### Everytime you run test with --before argument it will set environment variable BEFORE_HOOK\n\n```typescript\n  if (process.env.BEFORE_HOOK) {\n    // do something here\n  }\n```\n\n##### Then execute tests with --before\n\n```bash\ngapi test --before\n```\n\n###### 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\n\n### Docker\n\n#### Following commands will start RabbitMQ, PostgreSQL, API, NGINX as a services you need DOCKER for them\n\n##### API will be served on https://localhost:80 and https://localhost:80/subscriptions\n\n#### To build project with Docker type:\n\n```bash\ngapi app build\n```\n\n#### To start project with Docker type:\n\n```bash\ngapi app start\n```\n\n#### To stop project type:\n\n```bash\ngapi app stop\n```\n\n### Workers\n\n#### All workers will be mapped as Proxy and will be reverted to https://localhost:80 and https://localhost:80/subscriptions\n\n##### So you don't have to worry about if some of your workers stopped responding\n\n###### TODO: Create monitoring APP for all workers and main API\n\n#### To start workers type\n\n```bash\ngapi workers start\n```\n\n#### To stop workers type\n\n```bash\ngapi workers stop\n```\n\n##### To add more workers\n\n###### By default there are 4 workers with 4 processes with \"exec_mode: cluster\" of the original process inside single docker container\n\n###### You can control Processes inside single docker container from \"root/process.yml\" file.\n\n```yml\napps:\n  - script   : './src/main.ts'\n    name     : 'APP'\n    exec_mode: 'cluster'\n    instances: 4\n\n```\n\n###### To map new worker as a stream open root/nginx/config/private/default\n\n```nginx\nupstream app_servers {\n    server 182.10.0.3:9000; # Main process\n    server 182.10.0.21:9000; # Worker 1\n    server 182.10.0.22:9000; # Worker 2\n    server 182.10.0.23:9000; # Worker 3\n    server 182.10.0.24:9000; # Worker 4\n\n    # Add more workers here\n    # server 182.10.0.25:9000; # Worker 5\n}\n\nserver {\n    listen 80;\n    server_name api.yourdomain.com;\n    access_log api-yourdomain.access.log;\n\n    location / {\n       proxy_set_header Upgrade $http_upgrade;\n       proxy_set_header Connection \"upgrade\";\n       client_max_body_size 50M;\n       proxy_set_header Host $http_host;\n       proxy_set_header X-Real-IP $remote_addr;\n       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n       proxy_set_header X-Forwarded-Proto $scheme;\n       proxy_set_header X-Frame-Options SAMEORIGIN;\n       proxy_buffers 256 16k;\n\t     proxy_buffering off;\n       proxy_buffer_size 16k;\n       proxy_read_timeout 600s;\n       proxy_pass http://app_servers;\n    }\n\n    location /subscriptions {\n         # prevents 502 bad gateway error\n        proxy_buffers 8 32k;\n        proxy_buffer_size 64k;\n\n        # redirect all HTTP traffic to localhost:9000;\n        proxy_pass http://app_servers/subscriptions;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header Host $http_host;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        #proxy_set_header X-NginX-Proxy true;\n\n        # enables WS support\n        proxy_http_version 1.1;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection \"upgrade\";\n\t      proxy_buffering off;\n        proxy_read_timeout 999999999;\n\n    }\n    if ($scheme = http) {\n       return 301 https://$server_name$request_uri;\n    }\n    listen 443;\n    ssl on;\n    ssl_certificate         /usr/share/certs/cert.pem;\n    ssl_certificate_key     /usr/share/certs/cert.key;\n}\n\n\n```\n\n###### When you add another worker it should be on different IP with same port 9000\n\n###### Open root/gapi.conf.yml file you will find this file:\n\n```yml\nconfig:\n# Application configuration\n  app: \n    local:\n      API_PORT: 9000\n      API_CERT: ./cert.key\n      NODE_ENV: development\n      AMQP_HOST: 182.10.0.5\n      AMQP_PORT: 5672\n      GRAPHIQL: true\n      GRAPHIQL_TOKEN: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImtyaXN0aXFuLnRhY2hldkBnbWFpbC5jb20iLCJpZCI6MSwic2NvcGUiOlsiQURNSU4iXSwiaWF0IjoxNTIwMjkxMzkyfQ.9hpIDPkSiGvjTmUEyg_R_izW-ra2RzzLbe3Uh3IFsZg\n      ENDPOINT_TESTING: http://localhost:9000/graphql\n      TOKEN_TESTING: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImtyaXN0aXFuLnRhY2hldkBnbWFpbC5jb20iLCJzY29wZSI6WyJBRE1JTiJdLCJpZCI6MSwiaWF0IjoxNTE2OTk2MzYxfQ.7ANr5VHrViD3NkCaDr0nSWYwk46UAEbOwB52pqye4AM\n    prod:\n      API_PORT: 9000\n      API_CERT: ./cert.key\n      NODE_ENV: production\n      AMQP_HOST: 182.10.0.5\n      AMQP_PORT: 5672\n# Testing configuration for local(dev) or worker(running tests as a separate worker with separate environment)\n  test: \n    local: extends app/local\n    worker:\n      API_PORT: 9000\n      API_CERT: ./cert.key\n      NODE_ENV: production\n      AMQP_HOST: 182.10.0.5\n      AMQP_PORT: 5672\n      ENDPOINT_TESTING: http://182.10.0.101:9000/graphql\n      TOKEN_TESTING: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImtyaXN0aXFuLnRhY2hldkBnbWFpbC5jb20iLCJzY29wZSI6WyJBRE1JTiJdLCJpZCI6MSwiaWF0IjoxNTE2OTk2MzYxfQ.7ANr5VHrViD3NkCaDr0nSWYwk46UAEbOwB52pqye4AM\n\n  schema:\n    introspectionEndpoint: http://localhost:9000/graphql\n    introspectionOutputFolder: ./src/app/core/api-introspection\n\ncommands:\n\n  testing:\n    stop:\n      - docker rm -f gapi-api-prod-worker-tests-executor\n      - docker rm -f gapi-api-prod-worker-tests-provider\n    start:\n      - gapi testing start-provider\n      - sleep 10\n      - gapi testing start-executor\n      - echo Cleaning...\n      - gapi testing stop\n    start-provider: docker run -d --network=gapiapiprod_gapi --ip=182.10.0.101 --name gapi-api-prod-worker-tests-provider gapi/api/prod\n    start-executor:\n      - docker run -d --network=gapiapiprod_gapi --ip=182.10.0.100 --name gapi-api-prod-worker-tests-executor gapi/api/prod\n      - docker exec gapi-api-prod-worker-tests-provider npm -v\n      - gapi test --worker --before\n\n  workers:\n    start:\n      - gapi workers start-1\n      - gapi workers start-2\n      - gapi workers start-3\n      - gapi workers start-4\n    stop:\n      - docker rm -f gapi-api-prod-worker-1\n      - docker rm -f gapi-api-prod-worker-2\n      - docker rm -f gapi-api-prod-worker-3\n      - docker rm -f gapi-api-prod-worker-4\n    start-1: docker run -d --network=gapiapiprod_gapi --ip=182.10.0.21 --name gapi-api-prod-worker-1 gapi/api/prod\n    start-2: docker run -d --network=gapiapiprod_gapi --ip=182.10.0.22 --name gapi-api-prod-worker-2 gapi/api/prod\n    start-3: docker run -d --network=gapiapiprod_gapi --ip=182.10.0.23 --name gapi-api-prod-worker-3 gapi/api/prod\n    start-4: docker run -d --network=gapiapiprod_gapi --ip=182.10.0.24 --name gapi-api-prod-worker-4 gapi/api/prod\n    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/prod\n\n  app:\n    start:\n      - docker-compose -p gapi-api-prod up --force-recreate -d\n      - gapi rabbitmq enable-dashboard\n    stop:\n      - gapi nginx stop\n      - gapi api stop\n      - gapi rabbitmq stop\n      - gapi postgres stop\n    build: docker build -t gapi/api/prod .\n\n  api:\n    stop: docker rm -f gapi-api-prod\n\n  nginx:\n    stop: docker rm -f gapi-api-nginx\n\n  postgres:\n    stop: docker rm -f gapi-api-postgres\n\n  rabbitmq:\n    stop: docker rm -f gapi-api-rabbitmq\n    restart: docker restart gapi-api-rabbitmq\n    enable-dashboard: docker exec gapi-api-rabbitmq rabbitmq-plugins enable rabbitmq_management\n\n# You can define your custom commands for example \n# commands:\n#   your-cli:\n#     my-command: 'npm -v'\n# This command can be executed as \"gapi your-cli my-command\"\n```\n\n###### Adding one more worker:\n\n```yml\nstart-5: 'docker run -d --network=gapiapiprod_gapi --ip=182.10.0.25 --name gapi-api-prod-worker-5 -p 9005:9000 gapi/api/prod'\n```\n\n###### Then edit start task inside workers to start new worker 5\n\n```yml\nstart: 'gapi workers start-1 \u0026\u0026 gapi workers start-2 \u0026\u0026 gapi workers start-3 \u0026\u0026 gapi workers start-4 \u0026 gapi workers start-5'\n```\n\n###### Thats' it!! Now you have 4 processes like CLUSTERS inside 1 docker container with ip 182.10.0.25 and external port(optional) 9005;\n\n###### You can specify worker also without port because all workers are inside internal network called \"gapiapiprod_gapi\"\n\n###### 182.10.0.21/22/23/24/25:9000\n\n```yml\nstart-5: 'docker run -d --network=gapiapiprod_gapi --ip=182.10.0.25 --name gapi-api-prod-worker-5 gapi/api/prod'\n```\n\n###### If you want to change port forwarding to another port you need to set just nginx configuration:\n\n```yml\n  nginx:\n    image: sameersbn/nginx:1.10.1-5\n    ports:\n      - \"81:80\"\n      - \"443:443\"\n```\n\n###### Now you can find your API served onto https://localhost:81/ and https://localhost:81/subscriptions\n\n###### All workers don't care about that  because they will be served and mapped from nginx to port 80\n\n###### You can check docker-compose file to configurate environment variables\n\n```yml\nversion: '2'\nservices:\n\n  nginx:\n    image: sameersbn/nginx:1.10.1-5\n    ports:\n      - \"80:80\"\n      - \"443:443\"\n    volumes:\n      - ./nginx/config:/etc/nginx\n      - ./nginx/html:/usr/share/nginx/html/\n      - ./nginx/certs:/usr/share/certs\n    restart: always\n    container_name: gapi-api-nginx\n    networks:\n      gapi:\n        ipv4_address: 182.10.0.2\n\n  api:\n    image: gapi/api/prod:latest\n    ports:\n      - \"9000\"\n    restart: always\n    mem_limit: 1000000000\n    cpu_shares: 73\n    container_name: gapi-api-prod\n    depends_on:\n      - nginx\n      - rabbitMq\n    networks:\n      gapi:\n        ipv4_address: 182.10.0.3\n\n  rabbitMq:\n    image: rabbitmq:3.7.2\n    ports:\n      - \"15672:15672\"\n      - \"5672:5672\"\n      - \"5671:5671\"\n      - \"4369:4369\"\n    restart: always\n    container_name: gapi-api-rabbitmq\n    networks:\n      gapi:\n        ipv4_address: 182.10.0.5\n\nnetworks:\n  gapi:\n    driver: bridge\n    ipam:\n     config:\n       - subnet: 182.10.0.0/16\n         gateway: 182.10.0.1\n\n```\n\n##### After successfully started project you can open your browser to localhost:80 or 182.10.0.3:9000 the api will be served there\n\n\nTODO: Better documentation...\n\nEnjoy ! :)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstradivario%2Fgapi-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstradivario%2Fgapi-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstradivario%2Fgapi-starter/lists"}