From 5bd2f5a339af51abc3e29fe94d84c12965f68273 Mon Sep 17 00:00:00 2001 From: Vikram Rangnekar Date: Sat, 13 Apr 2019 09:12:41 -0400 Subject: [PATCH] Add an install guide --- docs/README.md | 7 ++- docs/guide.md | 68 +++++++---------------- docs/install.md | 141 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 49 deletions(-) create mode 100644 docs/install.md diff --git a/docs/README.md b/docs/README.md index c7cbba6..8effab4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -38,7 +38,12 @@ open http://localhost:3000 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 query { diff --git a/docs/guide.md b/docs/guide.md index bb9ece3..c0e87f4 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -37,9 +37,9 @@ open http://localhost:3000 open http://localhost:8080 ``` -::: 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/ +::: 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/) ::: #### Trying out GraphQL @@ -49,7 +49,7 @@ We currently support the `query` action which is used for fetching data. Support #### GQL Query ```graphql -query { +query { users { id email @@ -67,7 +67,7 @@ query { ``` 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. @@ -167,7 +167,7 @@ not | not: { or : { quantity : { eq: 0 }, price : { eq: 0 } } } | NOT (quantity 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 gt, greater_than | id: { gt: 100 } | id > 100 lt, lesser_than | id: { gt: 100 } | id < 100 @@ -230,7 +230,7 @@ query { # no duplicate prices returned distinct: [ price ] - + # only items with an id >= 30 and < 30 are returned where: { id: { and: { greater_or_equals: 20, lt: 28 } } }) { id @@ -253,7 +253,7 @@ query { # Return only matches where the price is less than 10 where: { price: { lt: 10 } } - + # Use the search_rank to order from the best match to the worst order_by: { search_rank: desc }) { 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) -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 -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. @@ -379,7 +379,7 @@ auth: auth: type: jwt cookie: _app_session - + jwt: provider: auth0 #none secret: abc335bfcfdb04e50db5bb0a4d67ab9 @@ -428,7 +428,7 @@ auth_fail_block: never # person: people # sheep: sheep -auth: +auth: # Can be 'rails' or 'jwt' type: rails cookie: _app_session @@ -444,7 +444,7 @@ auth: # Found in 'Rails.application.config.secret_key_base' secret_key_base: 0a248500a64c01184edb4d7ad3a805488f8097ac761b76aaa6c17c01dcb7af03a2f18ba61b2868134b9c7b79a122bc0dadff4367414a2d173297bfea92be5566 - + # Remote cookie store. (memcache or redis) # url: redis://127.0.0.1:6379 # password: test @@ -471,16 +471,16 @@ database: password: '' # pool_size: 10 # 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: account_id: "select account_id from users where id = $user_id" # Define defaults to for the field key and values below defaults: filter: ["{ user_id: { eq: $user_id } }"] - + # Fields and table names that you wish to block blacklist: - ar_internal_metadata @@ -500,10 +500,10 @@ database: filter: [ "{ price: { gt: 0 } }", "{ price: { lt: 8 } }" - ] + ] - name: customers - # No filter is used for this field not + # No filter is used for this field not # even defaults.filter filter: none @@ -537,34 +537,7 @@ SG_AUTH_RAILS_REDIS_PASSWORD SG_AUTH_JWT_PUBLIC_KEY_FILE ``` -## Deploying 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 - -### 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 +## 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. @@ -587,7 +560,6 @@ docker-compose up ``` - ## MIT License -MIT Licensed | Copyright © 2018-present Vikram Rangnekar \ No newline at end of file +MIT Licensed | Copyright © 2018-present Vikram Rangnekar diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 0000000..2470ad0 --- /dev/null +++ b/docs/install.md @@ -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. + +