Add an install guide
This commit is contained in:
parent
dd3132bda0
commit
5bd2f5a339
|
@ -38,7 +38,12 @@ open http://localhost:3000
|
||||||
open http://localhost:8080
|
open http://localhost:8080
|
||||||
```
|
```
|
||||||
|
|
||||||
## Try this GraphQL query
|
::: warning DEMO REQUIREMENTS
|
||||||
|
This demo requires `docker` you can either install it using `brew` or from the
|
||||||
|
docker website [https://docs.docker.com/docker-for-mac/install/](https://docs.docker.com/docker-for-mac/install/)
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Try out GraphQL
|
||||||
|
|
||||||
```graphql
|
```graphql
|
||||||
query {
|
query {
|
||||||
|
|
|
@ -37,9 +37,9 @@ open http://localhost:3000
|
||||||
open http://localhost:8080
|
open http://localhost:8080
|
||||||
```
|
```
|
||||||
|
|
||||||
::: warning DEMO REQUIREMENTS
|
::: warning DEMO REQUIREMENTS
|
||||||
This demo requires `docker` you can either install it using `brew` or from the
|
This demo requires `docker` you can either install it using `brew` or from the
|
||||||
docker website https://docs.docker.com/docker-for-mac/install/
|
docker website [https://docs.docker.com/docker-for-mac/install/](https://docs.docker.com/docker-for-mac/install/)
|
||||||
:::
|
:::
|
||||||
|
|
||||||
#### Trying out GraphQL
|
#### Trying out GraphQL
|
||||||
|
@ -49,7 +49,7 @@ We currently support the `query` action which is used for fetching data. Support
|
||||||
#### GQL Query
|
#### GQL Query
|
||||||
|
|
||||||
```graphql
|
```graphql
|
||||||
query {
|
query {
|
||||||
users {
|
users {
|
||||||
id
|
id
|
||||||
email
|
email
|
||||||
|
@ -67,7 +67,7 @@ query {
|
||||||
```
|
```
|
||||||
|
|
||||||
The above GraphQL query returns the JSON result below. It handles all
|
The above GraphQL query returns the JSON result below. It handles all
|
||||||
kinds of complexity without you having to writing a line of code.
|
kinds of complexity without you having to writing a line of code.
|
||||||
|
|
||||||
For example there is a while greater than `gt` and a limit clause on a child field. And the `avatar` field is renamed to `picture`. The `password` field is blocked and not returned. Finally the relationship between the `users` table and the `products` table is auto discovered and used.
|
For example there is a while greater than `gt` and a limit clause on a child field. And the `avatar` field is renamed to `picture`. The `password` field is blocked and not returned. Finally the relationship between the `users` table and the `products` table is auto discovered and used.
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ not | not: { or : { quantity : { eq: 0 }, price : { eq: 0 } } } | NOT (quantity
|
||||||
|
|
||||||
Name | Example | Explained |
|
Name | Example | Explained |
|
||||||
--- | --- | --- |
|
--- | --- | --- |
|
||||||
eq, equals | id : { eq: 100 } | id = 100
|
eq, equals | id : { eq: 100 } | id = 100
|
||||||
neq, not_equals | id: { not_equals: 100 } | id != 100
|
neq, not_equals | id: { not_equals: 100 } | id != 100
|
||||||
gt, greater_than | id: { gt: 100 } | id > 100
|
gt, greater_than | id: { gt: 100 } | id > 100
|
||||||
lt, lesser_than | id: { gt: 100 } | id < 100
|
lt, lesser_than | id: { gt: 100 } | id < 100
|
||||||
|
@ -230,7 +230,7 @@ query {
|
||||||
|
|
||||||
# no duplicate prices returned
|
# no duplicate prices returned
|
||||||
distinct: [ price ]
|
distinct: [ price ]
|
||||||
|
|
||||||
# only items with an id >= 30 and < 30 are returned
|
# only items with an id >= 30 and < 30 are returned
|
||||||
where: { id: { and: { greater_or_equals: 20, lt: 28 } } }) {
|
where: { id: { and: { greater_or_equals: 20, lt: 28 } } }) {
|
||||||
id
|
id
|
||||||
|
@ -253,7 +253,7 @@ query {
|
||||||
|
|
||||||
# Return only matches where the price is less than 10
|
# Return only matches where the price is less than 10
|
||||||
where: { price: { lt: 10 } }
|
where: { price: { lt: 10 } }
|
||||||
|
|
||||||
# Use the search_rank to order from the best match to the worst
|
# Use the search_rank to order from the best match to the worst
|
||||||
order_by: { search_rank: desc }) {
|
order_by: { search_rank: desc }) {
|
||||||
id
|
id
|
||||||
|
@ -331,9 +331,9 @@ You can only have one type of auth enabled. You can either pick Rails or JWT. Un
|
||||||
|
|
||||||
### Rails Auth (Devise / Warden)
|
### Rails Auth (Devise / Warden)
|
||||||
|
|
||||||
Almost all Rails apps use Devise or Warden for authentication. Once the user is
|
Almost all Rails apps use Devise or Warden for authentication. Once the user is
|
||||||
authenticated a session is created with the users ID. The session can either be
|
authenticated a session is created with the users ID. The session can either be
|
||||||
stored in the users browser as a cookie, memcache or redis. If memcache or redis is used then a cookie is set in the users browser with just the session id.
|
stored in the users browser as a cookie, memcache or redis. If memcache or redis is used then a cookie is set in the users browser with just the session id.
|
||||||
|
|
||||||
Super Graph can handle all these variations including the old and new session formats. Just enable the right `auth` config based on how your rails app is configured.
|
Super Graph can handle all these variations including the old and new session formats. Just enable the right `auth` config based on how your rails app is configured.
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ auth:
|
||||||
auth:
|
auth:
|
||||||
type: jwt
|
type: jwt
|
||||||
cookie: _app_session
|
cookie: _app_session
|
||||||
|
|
||||||
jwt:
|
jwt:
|
||||||
provider: auth0 #none
|
provider: auth0 #none
|
||||||
secret: abc335bfcfdb04e50db5bb0a4d67ab9
|
secret: abc335bfcfdb04e50db5bb0a4d67ab9
|
||||||
|
@ -428,7 +428,7 @@ auth_fail_block: never
|
||||||
# person: people
|
# person: people
|
||||||
# sheep: sheep
|
# sheep: sheep
|
||||||
|
|
||||||
auth:
|
auth:
|
||||||
# Can be 'rails' or 'jwt'
|
# Can be 'rails' or 'jwt'
|
||||||
type: rails
|
type: rails
|
||||||
cookie: _app_session
|
cookie: _app_session
|
||||||
|
@ -444,7 +444,7 @@ auth:
|
||||||
|
|
||||||
# Found in 'Rails.application.config.secret_key_base'
|
# Found in 'Rails.application.config.secret_key_base'
|
||||||
secret_key_base: 0a248500a64c01184edb4d7ad3a805488f8097ac761b76aaa6c17c01dcb7af03a2f18ba61b2868134b9c7b79a122bc0dadff4367414a2d173297bfea92be5566
|
secret_key_base: 0a248500a64c01184edb4d7ad3a805488f8097ac761b76aaa6c17c01dcb7af03a2f18ba61b2868134b9c7b79a122bc0dadff4367414a2d173297bfea92be5566
|
||||||
|
|
||||||
# Remote cookie store. (memcache or redis)
|
# Remote cookie store. (memcache or redis)
|
||||||
# url: redis://127.0.0.1:6379
|
# url: redis://127.0.0.1:6379
|
||||||
# password: test
|
# password: test
|
||||||
|
@ -471,16 +471,16 @@ database:
|
||||||
password: ''
|
password: ''
|
||||||
# pool_size: 10
|
# pool_size: 10
|
||||||
# max_retries: 0
|
# max_retries: 0
|
||||||
# log_level: "debug"
|
# log_level: "debug"
|
||||||
|
|
||||||
# Define variables here that you want to use in filters
|
# Define variables here that you want to use in filters
|
||||||
variables:
|
variables:
|
||||||
account_id: "select account_id from users where id = $user_id"
|
account_id: "select account_id from users where id = $user_id"
|
||||||
|
|
||||||
# Define defaults to for the field key and values below
|
# Define defaults to for the field key and values below
|
||||||
defaults:
|
defaults:
|
||||||
filter: ["{ user_id: { eq: $user_id } }"]
|
filter: ["{ user_id: { eq: $user_id } }"]
|
||||||
|
|
||||||
# Fields and table names that you wish to block
|
# Fields and table names that you wish to block
|
||||||
blacklist:
|
blacklist:
|
||||||
- ar_internal_metadata
|
- ar_internal_metadata
|
||||||
|
@ -500,10 +500,10 @@ database:
|
||||||
filter: [
|
filter: [
|
||||||
"{ price: { gt: 0 } }",
|
"{ price: { gt: 0 } }",
|
||||||
"{ price: { lt: 8 } }"
|
"{ price: { lt: 8 } }"
|
||||||
]
|
]
|
||||||
|
|
||||||
- name: customers
|
- name: customers
|
||||||
# No filter is used for this field not
|
# No filter is used for this field not
|
||||||
# even defaults.filter
|
# even defaults.filter
|
||||||
filter: none
|
filter: none
|
||||||
|
|
||||||
|
@ -537,34 +537,7 @@ SG_AUTH_RAILS_REDIS_PASSWORD
|
||||||
SG_AUTH_JWT_PUBLIC_KEY_FILE
|
SG_AUTH_JWT_PUBLIC_KEY_FILE
|
||||||
```
|
```
|
||||||
|
|
||||||
## Deploying Super Graph
|
## Developing Super Graph
|
||||||
|
|
||||||
How do I deploy the Super Graph service with my existing rails app? You have several options here. Esentially you need to ensure your app's session cookie will be passed to this service.
|
|
||||||
|
|
||||||
### Custom Docker Image
|
|
||||||
|
|
||||||
Create a `Dockerfile` like the one below to roll your own
|
|
||||||
custom Super Graph docker image. And to build it `docker build -t my-super-graph .`
|
|
||||||
|
|
||||||
```docker
|
|
||||||
FROM dosco/super-graph:latest
|
|
||||||
WORKDIR /app
|
|
||||||
COPY *.yml ./
|
|
||||||
```
|
|
||||||
|
|
||||||
### Deploy under a subdomain
|
|
||||||
For this to work you have to ensure that the option `:domain => :all` is added to your rails app config `Application.config.session_store` this will cause your rails app to create session cookies that can be shared with sub-domains. More info here <http://excid3.com/blog/sharing-a-devise-user-session-across-subdomains-with-rails-3/>
|
|
||||||
|
|
||||||
### With an NGINX loadbalancer
|
|
||||||
I'm sure you know how to configure it so that the Super Graph endpoint path `/api/v1/graphql` is routed to wherever you have this service installed within your architecture.
|
|
||||||
|
|
||||||
### On Kubernetes
|
|
||||||
If your Rails app runs on Kubernetes then ensure you have an ingress config deployed that points the path to the service that you have deployed Super Graph under.
|
|
||||||
|
|
||||||
### JWT tokens (Auth0, etc)
|
|
||||||
In that case deploy under a subdomain and configure this service to use JWT authentication. You will need the public key file or secret key. Ensure your web app passes the JWT token with every GQL request in the Authorize header as a `bearer` token.
|
|
||||||
|
|
||||||
## Developing Super Graph
|
|
||||||
|
|
||||||
If you want to build and run Super Graph from code then the below commands will build the web ui and launch Super Graph in developer mode with a watcher to rebuild on code changes. And the demo rails app is also launched to make it essier to test changes.
|
If you want to build and run Super Graph from code then the below commands will build the web ui and launch Super Graph in developer mode with a watcher to rebuild on code changes. And the demo rails app is also launched to make it essier to test changes.
|
||||||
|
|
||||||
|
@ -587,7 +560,6 @@ docker-compose up
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## MIT License
|
## MIT License
|
||||||
|
|
||||||
MIT Licensed | Copyright © 2018-present Vikram Rangnekar
|
MIT Licensed | Copyright © 2018-present Vikram Rangnekar
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
---
|
||||||
|
sidebar: auto
|
||||||
|
---
|
||||||
|
|
||||||
|
## How to deploy Super Graph
|
||||||
|
|
||||||
|
Since you're reading this you're probably considering deploying Super Graph. You're in luck it's really easy and there are several ways to choose from. Keep in mind Super Graph can be used as a pre-built docker image or you can easily customize it and build your own docker image.
|
||||||
|
|
||||||
|
### Alongside an existing Rails app
|
||||||
|
|
||||||
|
Super Graph can read Rails session cookies. Like those created by authentication gems (Devise or Warden). Based on how you've configured your Rails app the cookie can be signed, encrypted, both, include the user ID or just have the ID of the session. If you have choosen to use Redis or Memcache as your session store then Super Graph can read the session cookie and then lookup the user in the session store. In short it works really well with any kind of Rails app setup.
|
||||||
|
|
||||||
|
For any of this to work Super Graph must be deployed in a way that make the browser sent your apps cookie to it along with the GraphQL query. This means Super Graph should be on the same domain as your app or a subdomain.
|
||||||
|
|
||||||
|
::: tip I need an example
|
||||||
|
Say your Rails app runs on `myrailsapp.com` then Super Graph should be on the same domain or on a subdomain like `graphql.myrailsapp.com`. If you choose subdomain read below.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Custom Docker Image
|
||||||
|
|
||||||
|
You might find the need to customize the Super Graph config file to fit your app and then package it into a docker image. This is easy to do below is an example `Dockerfile` to do exactly this. And to build it `docker build -t my-super-graph .`
|
||||||
|
|
||||||
|
```docker
|
||||||
|
FROM dosco/super-graph:latest
|
||||||
|
WORKDIR /app
|
||||||
|
COPY *.yml ./
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deploy under a subdomain
|
||||||
|
|
||||||
|
For this to work you have to ensure that the option `:domain => :all` is added to your Rails app config `Application.config.session_store` this will cause your rails app to create session cookies that can be shared with sub-domains. More info here [/sharing-a-devise-user-session-across-subdomains-with-rails](http://excid3.com/blog/sharing-a-devise-user-session-across-subdomains-with-rails-3/)
|
||||||
|
|
||||||
|
### With an NGINX loadbalancer
|
||||||
|
|
||||||
|
If you're infrastructure is fronted by NGINX then it should be configured so that all requests to your GraphQL API path are proxyed to Super Graph. In the example NGINX config below all requests to the path `/api/v1/graphql` are routed to wherever you have Super Graph installed within your architecture. This example is derived from the config file example at [/microservices-nginx-gateway/nginx.conf](https://github.com/launchany/microservices-nginx-gateway/blob/master/nginx.conf)
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
# Configuration for the server
|
||||||
|
server {
|
||||||
|
|
||||||
|
# Running port
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
# Proxy the graphql api path to Super Graph
|
||||||
|
location /api/v1/graphql {
|
||||||
|
|
||||||
|
proxy_pass http://super-graph-service:8080;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $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-Host $server_name;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Proxying all other paths to your Rails app
|
||||||
|
location / {
|
||||||
|
|
||||||
|
proxy_pass http://your-rails-app:3000;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $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-Host $server_name;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### On Kubernetes
|
||||||
|
|
||||||
|
If your Rails app runs on Kubernetes then ensure you have an ingress config deployed that points the path to the service that you have deployed Super Graph under.
|
||||||
|
|
||||||
|
#### Ingress config
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: simple-rails-app
|
||||||
|
annotations:
|
||||||
|
nginx.ingress.kubernetes.io/rewrite-target: /
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: myrailsapp.com
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /api/v1/graphql
|
||||||
|
backend:
|
||||||
|
serviceName: graphql-service
|
||||||
|
servicePort: 8080
|
||||||
|
- path: /
|
||||||
|
backend:
|
||||||
|
serviceName: rails-app
|
||||||
|
servicePort: 3000
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Service and deployment config
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: graphql-service
|
||||||
|
labels:
|
||||||
|
run: super-graph
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- port: 8080
|
||||||
|
protocol: TCP
|
||||||
|
selector:
|
||||||
|
run: super-graph
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: super-graph
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
run: super-graph
|
||||||
|
replicas: 2
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
run: super-graph
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: super-graph
|
||||||
|
image: docker.io/dosco/super-graph:latest
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
```
|
||||||
|
|
||||||
|
### JWT tokens (Auth0, etc)
|
||||||
|
|
||||||
|
In that case deploy under a subdomain and configure this service to use JWT authentication. You will need the public key file or secret key. Ensure your web app passes the JWT token with every GQL request in the Authorize header as a `bearer` token.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue