Git Product home page Git Product logo

leaderit / graphql-postgres-template Goto Github PK

View Code? Open in Web Editor NEW
9.0 2.0 1.0 3.85 MB

Template for GraphQL API based on PostgreSQL database server, Hasura GraphQL engine, Redis memory cache, Fastify nodejs server for custom business logics with authorisation and access control.

License: MIT License

SCSS 0.12% Vue 5.89% JavaScript 82.50% Shell 2.35% Dockerfile 4.73% PLpgSQL 4.41%
graphql postgresql hasura docker graphql-hasura graphql-api redis minio nginx pgadmin

graphql-postgres-template's Introduction

GraphQL backend based on PostgreSQL database with Auth, Access rights and custom Business Logic

Quick start

Pre-requisites : docker, git, docker-compose must be installed.

mkdir my-project
cd my-project
curl https://raw.githubusercontent.com/leaderit/graphql-postgres-template/main/configure.sh | bash -s --

Warning

Always use HTTPS connection for keep your backend in secure.

Introduction

The GraphQL application interface based on Hasura, PostgreSQL server and NodeJS framework Fastify for custom busines logic. Al services composed into docker containers.

The Template goals:

  • Speed up a development of complex backedns for Web and Mobile applications.
  • Make the development easy, secure and fail-safe.

Russian

Сервис интерфейса прикладнох программ на базе GraphQL интерфейса Hasura, сервера SQL PostgreSQL и обработчика бизнес логики на базе NodeJS сервера Fastify собран для облегчения разработки серверной части для Web и мобильных приложений.

Выбранная комбинация серверных решений обладает следующими преимуществами.

  • Высокая производительность
  • Легкая расширяемость
  • Поддержка внешних REST API
  • Интеграция внешних GraphQL сервисов
  • Подписка на обновления через Web Sockets
  • Удобная GraphQL консоль для настройки и отладки запросов и данных
  • Многое другое

Функциональные возможности сервиса

Registrations and Authorisations

The template provides a GraphQL API for this, described in

Registration and Authorisation

...

Users

Roles

Organisations (Companies, Business units, etc.)

Organisations Users

Local Files Storage

  • Загрузка файлов через POST form/data средствами сервера Nginx
  • Доступ к данным о файлах в соответствии с ролью
  • Доступ к статическому содержимому файлов через NGINX с проверкой прав доступа через Backend
  • Ограничение размера загрузки
  • Ограничение скорости загрузки
  • Настраиваемые Файловые хранилища для данных пользователя, организации, общедоступные
  • Кеширование запросов доступа к файлам, сокращение времени проверки доступа до 3-х раза при повторных запросах
  • Ограничение загрузки содержимого файлов с проверкой прав доступа через Backend перед приемом содержимого файла.

Distributed Object Storage Min.IO

  • Integration Min.IO Storage API into backend server as standatd Fastify plugin
  • GraphQL: get direct object's url for upload
  • Upload an object via the direct url
  • Access to an object via the direct url
  • GraphQL: get direct object's url for access and download
  • GraphQL: copy an object
  • GraphQL: delete an object
  • GraphQL: move an object
  • Functional tests

Applications

It the template you can not access to docker services directly by securitu reason. You can access to the template subsystems via Nginx proxy only.

Default endpoints for access services are:

Details are in img/nginx/default.conf

Security

...

Настройка

Docker resources required

Данная система в минимальной конфигурации расчитана на комфортную работу около 10 000 пользователей c одновременной активностью по количеству запросов до 50 в секунду для обеспечения времени реакции менее 1 сек.

Минимальные требования по количеству ресурсов, выделенных для работы docker, чтобы все подсистемы работали корректно.

2 CPU 4Gb RAM

Я тестировал на MacBook Pro 2.4 GHz 8‑ядерный процессор Intel Core i9 Под Docker выделено 4Gb RAM, 2CPU, 4Gb swap file.

При этом за 18 минут тестирования было выполнено 30000 регистраций и разрегистраций новых пользователей. Таким образом в этой конфигурации выполнялось в среднем 56 запросов к API в 1 секунду.

На конфигурации 2 CPU и 8Gb RAM создание и удаление 100 000 пользователей заняло 1 час, что составляет примерно 56 запросов в секунду.

Увеличение CPU с 2-х до 4-х при 4Gb RAM не увеличило скорость выполнения запросов. Многопроцессорную оптимизацию сервиса необходимо выполнять дополнительно.

Увеличение RAM с 4-х до 8 Gb не увеличило скорость выполнения запросов.

Максимальная память ребуется для работы PostgreSQL и тут возможна оптимизации на уровне конфигурирования сервера БД.

Файл конфигурации .env

Скопируйте файл с примером конфигурации env-example в файл с именем .env и настройте парметры.

Установите имя вашего сервиса в списке контейнеров docker. Это имя используется как префикс для всех образов сервиса.

NAME=graphql-postgres-template

Установите значения паролей и портов чтобы иметь доступ извне к отдельным контейнерам.

Запуск сервиса в режиме отладки

Для отладки необходимо запустить сервис в консольном режиме.

docker-compose up

При этом вы будете видеть все сообoщения служб на консоли. При обновлении исходных текстовых файлов серверной части сервиса программа PM2 автоматически перестартует серверную часть и вы можете тестировать новый функционал.

Запуск сервиса в режиме демона

В режиме демона сервис может быть запущен командой

docker-compose up -d

Database setup

После запуска сервисов будеет создана пустая база данных PostgreSQL в папке db/postgres и Redis в папке db/redis.

Выполните создание таблиц, загрузку метаданных и данных по умолчанию для тестирования, введя команды:

./hasura-cli migrate apply
./hasura-cli metadata apply
./hasura-cli seeds apply

Повторный запуск команд на существующей базе данных может вызвать ошибку.

How to delete all migrations records

1. Run `./psql-cli`
2. Enter command: `DELETE FROM hdb_catalog.schema_migrations;`
3. Quit by `\q`

Запуск тестов

Для того, чтобы убедиться, что ваши настройки выполнены правильно и сервисы работают корректно запустите на настроенной базе занных тесты сервисов GraphQL API командой:

./run-tests 

Все тесты должны завершиться без ошибок.

Роли и права доступа

В сервисе используется ролевая модель доступа. Это означает, что все роли прописываются при настройке сервиса и доступ к данным осуществляется на основе прав конкретной роли пользователя, под которой он подключился к сервису.

Стандартные роли при создании сервиса следующие.

  • admin
  • anonymous
  • user
  • manager
  • orgadmin
  • owner

Список ролей для назначения пользователям записан в таблице БД roles. Этот список должен совпадать со списком ролей, прописанных в Hasura.

Вы можете добавить любые необходимые вам роли и настроить доступ к данным в зависимости от того, какую роль доступа имеет пользователь.

Номера ролей с 1 по 999 зарезервированы для системных целей. Используйте роли приложения начиная с номера 1000, который зарезервирован для простого пользователя без дополнительных полномочий.

Производственный режим

Загрузка на производственный сервер и настройка запуска.

Перенос сервса на другой сервер

Так как сервис выполняется в контейнерах docker для переноса сервиса на новый сервер вам достаточно

  • установить на нем docker и docker-compose
  • скопировать папку вашего сервиса со всем содержимым на новый сервер
  • корректно настроить файл .env на новый домен или сервер
  • выполнить docker-compose up -d

Обновление сервиса на новую версию

Чтобы обновить сервис на новую версию вам необходимо выполнить следующие шаги.

  • Сохранить ваши метаданные и базу данных старого сервера

    ./db-backup ./hasura-cli metadata export

  • При необходимости сохранить миграцию командой

    ./hasura-cli migrate create --from-server init

где init - имя миграциию если вы перед этим выгрузили другие миграцииб вам необходимо удалить дублирующиеся команды из новой миграции вручную. В противном случае мат как миграции выполняются последовательно и накладываются одна на другую, возможны конфликты.

  • Скачать и установить чистый шаблон сервиса на вашем новом сервере.

    git clone https://github.com/leaderit/graphql-postgres-template

  • Переименовать папку шаблона в папку с именем сервиса вашего проекта

    mv graphql-postgres-template graphql-my-project

  • Сохранить метаданные по умолчанию в другой папке

    mv ./db/metadata ./db/metadata.default

  • Скопировать файлы .env, последний файл *-backup.sql и папку ./db/metadata на новый сервер

  • настроить файл .env под новые сервер

  • Исправить метаданные вручную, добавив в ваши метаданные необходимые дополнения из данных по умолчанию

  • Исправить вручную ваши данные в файле *-backup.sql, добавив туда изменения структур из обновленной версии или создать специальную миграцию для обновления структуры

  • Восстановить ваши метаданные

    ./hasura-cli metadata apply

  • Восстановить данные

    ./db-restore [file name]-backup.sql

Plans and TODOs

I have plans to extend functionality of the template. I wrote it in the

TODO file

Copyrights

(c) Valerii Grazhdankin, Moscow, Russia, 2020-2021

graphql-postgres-template's People

Contributors

leaderit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

rohit0700

graphql-postgres-template's Issues

Unable to upload files

Hey!

I was unable to upload files based on postman collection shared.

Please guide.

Added token in Authorisation header and then tried to upload file through form-data in postman client.

The response was 403 Forbidden error.

Please guide.

I am sure I am missing something.

Screenshot is attached for info.

Screenshot 2021-01-23 at 3 08 50 PM

Disable x-hasura-admin-secret header in Nginx

Hi,

Can you please help me in disabling x-hasura-admin-secret in Nginx.

This will help me to make sure that no one can query even from postman client with x-hasura-admin-secret from outside network.

This will be great help.

Thank you.

Guidance on Table Permissions

Hi!

Request to please guide on table permissions.

I am adding a column to map X-Hasura-User-Id for row-level permissions.

This is a bit overhead.

I may have to add userid column for every table for mapping.

Is there a better way to deal this.

Kindly guide.

For example for a table named Transactions I added userid column just for mapping permissions with x-hasura-user-id

CREATE TABLE public.transactions
(
id uuid NOT NULL DEFAULT gen_random_uuid(),
"Transaction_name" text COLLATE pg_catalog."default" NOT NULL,
amount integer NOT NULL,
created_at timestamp with time zone NOT NULL DEFAULT now(),
updated_at timestamp with time zone NOT NULL DEFAULT now(),
userid text COLLATE pg_catalog."default",
CONSTRAINT transactions_pkey PRIMARY KEY (id)
)

image

Remove Nginx server header

Hi Brother!

I am trying to remove response header Server: nginx/1.19.6

Can you please guide.

I tried to add server_tokens '';
more_clear_headers Server;

in deafult.conf, the server becomes non responsive.

Error in accessing template backend.

Firstly...

Thank you for this wonderful template.

Kindly help me to resolve it.

When I tried to open minio through browser it asks for access key and secret key.They were never configured. Kindly help to configure them.

Also minio_root_user, minio_root_password,storage_user, storage_password were not available in env example file. I just added some values. Is it OK. I would like to implement and understand it. KINDLY HELP.

When I ./run-tests I get following error:

> [email protected] test /server
> tap -t36000 test/**/*.test.js

sh: 1: tap: not found
npm ERR! Test failed.  See above for more details.

I get following error in debug mode:

graphql-postgres-template-backend |     at Module.Hook._require.Module.require (/usr/local/lib/node_modules/pm2/node_modules/require-in-the-middle/index.js:61:29)
graphql-postgres-template-backend |     at require (internal/modules/cjs/helpers.js:88:18)
graphql-postgres-template-backend |     at Object.<anonymous> (/server/server.js:4:17)
graphql-postgres-template-backend |     at Module._compile (internal/modules/cjs/loader.js:1063:30)
graphql-postgres-template-backend |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
graphql-postgres-template-backend |     at Module.load (internal/modules/cjs/loader.js:928:32)
graphql-postgres-template-backend |     at Function.Module._load (internal/modules/cjs/loader.js:769:14)
graphql-postgres-template-backend |     at Object.<anonymous> (/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js:33:23)
graphql-postgres-template-backend |     at Module._compile (internal/modules/cjs/loader.js:1063:30) {
graphql-postgres-template-backend |   code: 'MODULE_NOT_FOUND',
graphql-postgres-template-backend |   requireStack: [ '/server/server.js' ]
graphql-postgres-template-backend | }
graphql-postgres-template-backend | 2021-01-19T10:42:17: PM2 log: App [server:0] exited with code [1] via signal [SIGINT]
graphql-postgres-template-backend | 2021-01-19T10:42:17: PM2 log: Script /server/server.js had too many unstable restarts (16). Stopped. "errored"
graphql-postgres-template-backend | 2021-01-19T10:42:18: PM2 log: 0 application online, retry = 3
graphql-postgres-template-backend | 2021-01-19T10:42:20: PM2 log: 0 application online, retry = 2
graphql-postgres-template-backend | 2021-01-19T10:42:22: PM2 log: 0 application online, retry = 1
graphql-postgres-template-backend | 2021-01-19T10:42:24: PM2 log: 0 application online, retry = 0
graphql-postgres-template-backend | 2021-01-19T10:42:24: PM2 log: [Watch] Stop watching server
graphql-postgres-template-backend | 2021-01-19T10:42:24: PM2 log: Stopping app:server id:0
graphql-postgres-template-backend | 2021-01-19T10:42:24: PM2 error: app=server id=0 does not have a pid
graphql-postgres-template-backend | 2021-01-19T10:42:24: PM2 log: PM2 successfully stopped
graphql-postgres-template-backend exited with code 0
graphql-postgres-template-backend | 2021-01-19T10:42:25: PM2 log: Launching in no daemon mode
graphql-postgres-template-backend | 2021-01-19T10:42:25: PM2 log: [Watch] Start watching server
graphql-postgres-template-backend | 2021-01-19T10:42:25: PM2 log: App [server:0] starting in -fork mode-
graphql-postgres-template-backend | 2021-01-19T10:42:25: PM2 log: App [server:0] online
graphql-postgres-template-backend | Error: Cannot find module 'fastify'
graphql-postgres-template-backend | Require stack:
graphql-postgres-template-backend | - /server/server.js
graphql-postgres-template-backend |     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
graphql-postgres-template-backend |     at Module.Hook._require.Module.require (/usr/local/lib/node_modules/pm2/node_modules/require-in-the-middle/index.js:61:29)
graphql-postgres-template-backend |     at require (internal/modules/cjs/helpers.js:88:18)
graphql-postgres-template-backend |     at Object.<anonymous> (/server/server.js:4:17)
graphql-postgres-template-backend |     at Module._compile (internal/modules/cjs/loader.js:1063:30)
graphql-postgres-template-backend |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
graphql-postgres-template-backend |     at Module.load (internal/modules/cjs/loader.js:928:32)
graphql-postgres-template-backend |     at Function.Module._load (internal/modules/cjs/loader.js:769:14)
graphql-postgres-template-backend |     at Object.<anonymous> (/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js:33:23)
graphql-postgres-template-backend |     at Module._compile (internal/modules/cjs/loader.js:1063:30) {
graphql-postgres-template-backend |   code: 'MODULE_NOT_FOUND',
graphql-postgres-template-backend |   requireStack: [ '/server/server.js' ]
graphql-postgres-template-backend | }
graphql-postgres-template-backend | 2021-01-19T10:42:25: PM2 log: App [server:0] exited with code [1] via signal [SIGINT]
graphql-postgres-template-backend | 2021-01-19T10:42:25: PM2 log: App [server:0] starting in -fork mode-
graphql-postgres-template-backend | 2021-01-19T10:42:25: PM2 log: App [server:0] online
graphql-postgres-template-backend | Error: Cannot find module 'fastify'
graphql-postgres-template-backend | Require stack:
graphql-postgres-template-backend | - /server/server.js
graphql-postgres-template-backend |     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
graphql-postgres-template-backend |     at Module.Hook._require.Module.require (/usr/local/lib/node_modules/pm2/node_modules/require-in-the-middle/index.js:61:29)
graphql-postgres-template-backend |     at require (internal/modules/cjs/helpers.js:88:18)
graphql-postgres-template-backend |     at Object.<anonymous> (/server/server.js:4:17)
graphql-postgres-template-backend |     at Module._compile (internal/modules/cjs/loader.js:1063:30)
graphql-postgres-template-backend |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
graphql-postgres-template-backend |     at Module.load (internal/modules/cjs/loader.js:928:32)
graphql-postgres-template-backend |     at Function.Module._load (internal/modules/cjs/loader.js:769:14)
graphql-postgres-template-backend |     at Object.<anonymous> (/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js:33:23)
graphql-postgres-template-backend |     at Module._compile (internal/modules/cjs/loader.js:1063:30) {
graphql-postgres-template-backend |   code: 'MODULE_NOT_FOUND',
graphql-postgres-template-backend |   requireStack: [ '/server/server.js' ]
graphql-postgres-template-backend | }
graphql-postgres-template-backend | 2021-01-19T10:42:26: PM2 log: App [server:0] exited with code [1] via signal [SIGINT]
graphql-postgres-template-backend | 2021-01-19T10:42:26: PM2 log: App [server:0] starting in -fork mode-
graphql-postgres-template-backend | 2021-01-19T10:42:26: PM2 log: App [server:0] online
graphql-postgres-template-backend | Error: Cannot find module 'fastify'
graphql-postgres-template-backend | Require stack:
graphql-postgres-template-backend | - /server/server.js
graphql-postgres-template-backend |     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
graphql-postgres-template-backend |     at Module.Hook._require.Module.require (/usr/local/lib/node_modules/pm2/node_modules/require-in-the-middle/index.js:61:29)
graphql-postgres-template-backend |     at require (internal/modules/cjs/helpers.js:88:18)
graphql-postgres-template-backend |     at Object.<anonymous> (/server/server.js:4:17)
graphql-postgres-template-backend |     at Module._compile (internal/modules/cjs/loader.js:1063:30)
graphql-postgres-template-backend |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
graphql-postgres-template-backend |     at Module.load (internal/modules/cjs/loader.js:928:32)
graphql-postgres-template-backend |     at Function.Module._load (internal/modules/cjs/loader.js:769:14)
graphql-postgres-template-backend |     at Object.<anonymous> (/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js:33:23)
graphql-postgres-template-backend |     at Module._compile (internal/modules/cjs/loader.js:1063:30) {
graphql-postgres-template-backend |   code: 'MODULE_NOT_FOUND',
graphql-postgres-template-backend |   requireStack: [ '/server/server.js' ]
graphql-postgres-template-backend | }
graphql-postgres-template-backend | 2021-01-19T10:42:26: PM2 log: App [server:0] exited with code [1] via signal [SIGINT]
graphql-postgres-template-backend | 2021-01-19T10:42:26: PM2 log: App [server:0] starting in -fork mode-
graphql-postgres-template-backend | 2021-01-19T10:42:26: PM2 log: App [server:0] online
graphql-postgres-template-backend | Error: Cannot find module 'fastify'
graphql-postgres-template-backend | Require stack:
graphql-postgres-template-backend | - /server/server.js
graphql-postgres-template-backend |     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
graphql-postgres-template-backend |     at Module.Hook._require.Module.require (/usr/local/lib/node_modules/pm2/node_modules/require-in-the-middle/index.js:61:29)
graphql-postgres-template-backend |     at require (internal/modules/cjs/helpers.js:88:18)
graphql-postgres-template-backend |     at Object.<anonymous> (/server/server.js:4:17)
graphql-postgres-template-backend |     at Module._compile (internal/modules/cjs/loader.js:1063:30)
graphql-postgres-template-backend |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
graphql-postgres-template-backend |     at Module.load (internal/modules/cjs/loader.js:928:32)
graphql-postgres-template-backend |     at Function.Module._load (internal/modules/cjs/loader.js:769:14)
graphql-postgres-template-backend |     at Object.<anonymous> (/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js:33:23)
graphql-postgres-template-backend |     at Module._compile (internal/modules/cjs/loader.js:1063:30) {
graphql-postgres-template-backend |   code: 'MODULE_NOT_FOUND',
graphql-postgres-template-backend |   requireStack: [ '/server/server.js' ]
graphql-postgres-template-backend | }
graphql-postgres-template-backend | 2021-01-19T10:42:26: PM2 log: App [server:0] exited with code [1] via signal [SIGINT]
graphql-postgres-template-backend | 2021-01-19T10:42:26: PM2 log: App [server:0] starting in -fork mode-
graphql-postgres-template-backend | 2021-01-19T10:42:26: PM2 log: App [server:0] online
graphql-postgres-template-backend | Error: Cannot find module 'fastify'
graphql-postgres-template-backend | Require stack:
graphql-postgres-template-backend | - /server/server.js
graphql-postgres-template-backend |     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
graphql-postgres-template-backend |     at Module.Hook._require.Module.require (/usr/local/lib/node_modules/pm2/node_modules/require-in-the-middle/index.js:61:29)
graphql-postgres-template-backend |     at require (internal/modules/cjs/helpers.js:88:18)
graphql-postgres-template-backend |     at Object.<anonymous> (/server/server.js:4:17)
graphql-postgres-template-backend |     at Module._compile (internal/modules/cjs/loader.js:1063:30)
graphql-postgres-template-backend |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
graphql-postgres-template-backend |     at Module.load (internal/modules/cjs/loader.js:928:32)
graphql-postgres-template-backend |     at Function.Module._load (internal/modules/cjs/loader.js:769:14)
graphql-postgres-template-backend |     at Object.<anonymous> (/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js:33:23)
graphql-postgres-template-backend |     at Module._compile (internal/modules/cjs/loader.js:1063:30) {
graphql-postgres-template-backend |   code: 'MODULE_NOT_FOUND',
graphql-postgres-template-backend |   requireStack: [ '/server/server.js' ]
graphql-postgres-template-backend | }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.