Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
0deb3596c5 | |||
b87ba1fcd0 | |||
8ae7210e70 | |||
f8aac8d4d7 | |||
34867a2733 | |||
4a8af69dd0 | |||
c74226208d | |||
6d2f334011 | |||
ff13f651d6 | |||
cabd2d81ae | |||
4edc15eb98 | |||
6bc66d28bc | |||
c797deb4d0 | |||
deb5b93c81 | |||
85a74ed30c | |||
9299855d8a | |||
450d77ccbd | |||
a1fa1f3e9e | |||
e68bdffa25 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -28,3 +28,7 @@ main
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.swp
|
.swp
|
||||||
main
|
main
|
||||||
|
super-graph
|
||||||
|
*-fuzz.zip
|
||||||
|
crashers
|
||||||
|
suppressions
|
13
.wtc.yaml
Normal file
13
.wtc.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
no_trace: false
|
||||||
|
debounce: 300 # if rule has no debounce, this will be used instead
|
||||||
|
ignore: \.git/
|
||||||
|
trig: [start, run] # will run on start
|
||||||
|
rules:
|
||||||
|
- name: start
|
||||||
|
- name: run
|
||||||
|
match: \.go$
|
||||||
|
ignore: web|examples|docs|_test\.go$
|
||||||
|
command: go run main.go serv
|
||||||
|
- name: test
|
||||||
|
match: _test\.go$
|
||||||
|
command: go test -cover {PKG}
|
@ -11,9 +11,8 @@ RUN apk update && \
|
|||||||
apk add --no-cache git && \
|
apk add --no-cache git && \
|
||||||
apk add --no-cache upx=3.95-r2
|
apk add --no-cache upx=3.95-r2
|
||||||
|
|
||||||
RUN go get -u github.com/shanzi/wu && \
|
RUN go get -u github.com/rafaelsq/wtc && \
|
||||||
go install github.com/shanzi/wu && \
|
go get -u github.com/GeertJohan/go.rice/rice
|
||||||
go get github.com/GeertJohan/go.rice/rice
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY . /app
|
COPY . /app
|
||||||
|
@ -46,6 +46,9 @@ This compiler is what sits at the heart of Super Graph with layers of useful fun
|
|||||||
|
|
||||||
## Contact me
|
## Contact me
|
||||||
|
|
||||||
|
I'm happy to help you deploy Super Graph so feel free to reach out over
|
||||||
|
Twitter or Discord.
|
||||||
|
|
||||||
[twitter/dosco](https://twitter.com/dosco)
|
[twitter/dosco](https://twitter.com/dosco)
|
||||||
|
|
||||||
[chat/super-graph](https://discord.gg/6pSWCTZ)
|
[chat/super-graph](https://discord.gg/6pSWCTZ)
|
||||||
|
@ -1,62 +1,5 @@
|
|||||||
# http://localhost:8080/
|
# http://localhost:8080/
|
||||||
|
|
||||||
variables {
|
|
||||||
"update": {
|
|
||||||
"name": "Wu-Tang",
|
|
||||||
"description": "No description needed"
|
|
||||||
},
|
|
||||||
"product_id": 1
|
|
||||||
}
|
|
||||||
|
|
||||||
mutation {
|
|
||||||
products(id: $product_id, update: $update) {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
description
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
variables {
|
|
||||||
"data": {
|
|
||||||
"email": "gfk@myspace.com",
|
|
||||||
"full_name": "Ghostface Killah",
|
|
||||||
"created_at": "now",
|
|
||||||
"updated_at": "now"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutation {
|
|
||||||
user(insert: $data) {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
variables {
|
|
||||||
"data": {
|
|
||||||
"product_id": 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutation {
|
|
||||||
products(id: $product_id, delete: true) {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
query {
|
|
||||||
users {
|
|
||||||
id
|
|
||||||
email
|
|
||||||
picture: avatar
|
|
||||||
products(limit: 2, where: {price: {gt: 10}}) {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
description
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
@ -79,6 +22,184 @@ mutation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
"update": {
|
||||||
|
"name": "Wu-Tang",
|
||||||
|
"description": "No description needed"
|
||||||
|
},
|
||||||
|
"product_id": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation {
|
||||||
|
products(id: $product_id, update: $update) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query {
|
||||||
|
users {
|
||||||
|
id
|
||||||
|
email
|
||||||
|
picture: avatar
|
||||||
|
products(limit: 2, where: {price: {gt: 10}}) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"name": "Gumbo1",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gumbo2",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation {
|
||||||
|
products(id: 199, delete: true) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"name": "Gumbo1",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gumbo2",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
query {
|
||||||
|
products {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"name": "Gumbo1",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gumbo2",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
query {
|
||||||
|
products {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
user {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
"data": {
|
||||||
|
"product_id": 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation {
|
||||||
|
products(id: $product_id, delete: true) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"name": "Gumbo1",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gumbo2",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
query {
|
||||||
|
products {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
price
|
||||||
|
users {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
variables {
|
||||||
|
"data": {
|
||||||
|
"email": "gfk@myspace.com",
|
||||||
|
"full_name": "Ghostface Killah",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation {
|
||||||
|
user(insert: $data) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"name": "Gumbo1",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gumbo2",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
query {
|
||||||
|
products {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
users {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
query {
|
query {
|
||||||
me {
|
me {
|
||||||
id
|
id
|
||||||
@ -102,3 +223,53 @@ mutation {
|
|||||||
description
|
description
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"name": "Gumbo1",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gumbo2",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
query {
|
||||||
|
product {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"name": "Gumbo1",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gumbo2",
|
||||||
|
"created_at": "now",
|
||||||
|
"updated_at": "now"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
query {
|
||||||
|
products {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
users {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
113
config/dev.yml
113
config/dev.yml
@ -22,7 +22,7 @@ enable_tracing: true
|
|||||||
|
|
||||||
# Watch the config folder and reload Super Graph
|
# Watch the config folder and reload Super Graph
|
||||||
# with the new configs when a change is detected
|
# with the new configs when a change is detected
|
||||||
reload_on_config_change: false
|
reload_on_config_change: true
|
||||||
|
|
||||||
# File that points to the database seeding script
|
# File that points to the database seeding script
|
||||||
# seed_file: seed.js
|
# seed_file: seed.js
|
||||||
@ -53,7 +53,7 @@ auth:
|
|||||||
|
|
||||||
# Comment this out if you want to disable setting
|
# Comment this out if you want to disable setting
|
||||||
# the user_id via a header. Good for testing
|
# the user_id via a header. Good for testing
|
||||||
header: X-User-ID
|
creds_in_header: true
|
||||||
|
|
||||||
rails:
|
rails:
|
||||||
# Rails version this is used for reading the
|
# Rails version this is used for reading the
|
||||||
@ -100,7 +100,7 @@ database:
|
|||||||
|
|
||||||
# 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 } }"]
|
# filters: ["{ user_id: { eq: $user_id } }"]
|
||||||
|
|
||||||
# Field and table names that you wish to block
|
# Field and table names that you wish to block
|
||||||
blocklist:
|
blocklist:
|
||||||
@ -111,42 +111,81 @@ database:
|
|||||||
- encrypted
|
- encrypted
|
||||||
- token
|
- token
|
||||||
|
|
||||||
tables:
|
tables:
|
||||||
- name: users
|
- name: customers
|
||||||
# This filter will overwrite defaults.filter
|
remotes:
|
||||||
# filter: ["{ id: { eq: $user_id } }"]
|
- name: payments
|
||||||
|
id: stripe_id
|
||||||
|
url: http://rails_app:3000/stripe/$id
|
||||||
|
path: data
|
||||||
|
# debug: true
|
||||||
|
pass_headers:
|
||||||
|
- cookie
|
||||||
|
set_headers:
|
||||||
|
- name: Host
|
||||||
|
value: 0.0.0.0
|
||||||
|
# - name: Authorization
|
||||||
|
# value: Bearer <stripe_api_key>
|
||||||
|
|
||||||
# - name: products
|
- # You can create new fields that have a
|
||||||
# # Multiple filters are AND'd together
|
# real db table backing them
|
||||||
# filter: [
|
name: me
|
||||||
# "{ price: { gt: 0 } }",
|
table: users
|
||||||
# "{ price: { lt: 8 } }"
|
|
||||||
# ]
|
|
||||||
|
|
||||||
- name: customers
|
roles_query: "SELECT * FROM users as usr WHERE id = $user_id"
|
||||||
# No filter is used for this field not
|
|
||||||
# even defaults.filter
|
|
||||||
filter: none
|
|
||||||
|
|
||||||
remotes:
|
roles:
|
||||||
- name: payments
|
- name: anon
|
||||||
id: stripe_id
|
tables:
|
||||||
url: http://rails_app:3000/stripe/$id
|
- name: products
|
||||||
path: data
|
limit: 10
|
||||||
# debug: true
|
|
||||||
pass_headers:
|
|
||||||
- cookie
|
|
||||||
set_headers:
|
|
||||||
- name: Host
|
|
||||||
value: 0.0.0.0
|
|
||||||
# - name: Authorization
|
|
||||||
# value: Bearer <stripe_api_key>
|
|
||||||
|
|
||||||
- # You can create new fields that have a
|
query:
|
||||||
# real db table backing them
|
columns: ["id", "name", "description" ]
|
||||||
name: me
|
aggregation: false
|
||||||
table: users
|
|
||||||
filter: ["{ id: { eq: $user_id } }"]
|
|
||||||
|
|
||||||
# - name: posts
|
insert:
|
||||||
# filter: ["{ account_id: { _eq: $account_id } }"]
|
block: false
|
||||||
|
|
||||||
|
update:
|
||||||
|
block: false
|
||||||
|
|
||||||
|
delete:
|
||||||
|
block: false
|
||||||
|
|
||||||
|
- name: user
|
||||||
|
tables:
|
||||||
|
- name: users
|
||||||
|
query:
|
||||||
|
filters: ["{ id: { _eq: $user_id } }"]
|
||||||
|
|
||||||
|
- name: products
|
||||||
|
query:
|
||||||
|
limit: 50
|
||||||
|
filters: ["{ user_id: { eq: $user_id } }"]
|
||||||
|
columns: ["id", "name", "description" ]
|
||||||
|
disable_functions: false
|
||||||
|
|
||||||
|
insert:
|
||||||
|
filters: ["{ user_id: { eq: $user_id } }"]
|
||||||
|
columns: ["id", "name", "description" ]
|
||||||
|
presets:
|
||||||
|
- created_at: "now"
|
||||||
|
|
||||||
|
update:
|
||||||
|
filters: ["{ user_id: { eq: $user_id } }"]
|
||||||
|
columns:
|
||||||
|
- id
|
||||||
|
- name
|
||||||
|
presets:
|
||||||
|
- updated_at: "now"
|
||||||
|
|
||||||
|
delete:
|
||||||
|
block: true
|
||||||
|
|
||||||
|
- name: admin
|
||||||
|
match: id = 1
|
||||||
|
tables:
|
||||||
|
- name: users
|
||||||
|
# query:
|
||||||
|
# filters: ["{ account_id: { _eq: $account_id } }"]
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# Inherit config from this other config file
|
||||||
|
# so I only need to overwrite some values
|
||||||
|
inherits: dev
|
||||||
|
|
||||||
app_name: "Super Graph Production"
|
app_name: "Super Graph Production"
|
||||||
host_port: 0.0.0.0:8080
|
host_port: 0.0.0.0:8080
|
||||||
web_ui: false
|
web_ui: false
|
||||||
@ -47,10 +51,6 @@ auth:
|
|||||||
type: rails
|
type: rails
|
||||||
cookie: _app_session
|
cookie: _app_session
|
||||||
|
|
||||||
# Comment this out if you want to disable setting
|
|
||||||
# the user_id via a header. Good for testing
|
|
||||||
header: X-User-ID
|
|
||||||
|
|
||||||
rails:
|
rails:
|
||||||
# Rails version this is used for reading the
|
# Rails version this is used for reading the
|
||||||
# various cookies formats.
|
# various cookies formats.
|
||||||
@ -80,65 +80,9 @@ database:
|
|||||||
type: postgres
|
type: postgres
|
||||||
host: db
|
host: db
|
||||||
port: 5432
|
port: 5432
|
||||||
dbname: {{app_name_slug}}_development
|
dbname: app_production
|
||||||
user: postgres
|
user: postgres
|
||||||
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
|
|
||||||
# sub-queries must be wrapped in ()
|
|
||||||
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 } }"]
|
|
||||||
|
|
||||||
# Field and table names that you wish to block
|
|
||||||
blocklist:
|
|
||||||
- ar_internal_metadata
|
|
||||||
- schema_migrations
|
|
||||||
- secret
|
|
||||||
- password
|
|
||||||
- encrypted
|
|
||||||
- token
|
|
||||||
|
|
||||||
tables:
|
|
||||||
- name: users
|
|
||||||
# This filter will overwrite defaults.filter
|
|
||||||
filter: ["{ id: { eq: $user_id } }"]
|
|
||||||
|
|
||||||
- name: products
|
|
||||||
# Multiple filters are AND'd together
|
|
||||||
filter: [
|
|
||||||
"{ price: { gt: 0 } }",
|
|
||||||
"{ price: { lt: 8 } }"
|
|
||||||
]
|
|
||||||
|
|
||||||
- name: customers
|
|
||||||
# No filter is used for this field not
|
|
||||||
# even defaults.filter
|
|
||||||
filter: none
|
|
||||||
|
|
||||||
# remotes:
|
|
||||||
# - name: payments
|
|
||||||
# id: stripe_id
|
|
||||||
# url: http://rails_app:3000/stripe/$id
|
|
||||||
# path: data
|
|
||||||
# # pass_headers:
|
|
||||||
# # - cookie
|
|
||||||
# # - host
|
|
||||||
# set_headers:
|
|
||||||
# - name: Authorization
|
|
||||||
# value: Bearer <stripe_api_key>
|
|
||||||
|
|
||||||
- # You can create new fields that have a
|
|
||||||
# real db table backing them
|
|
||||||
name: me
|
|
||||||
table: users
|
|
||||||
filter: ["{ id: { eq: $user_id } }"]
|
|
||||||
|
|
||||||
# - name: posts
|
|
||||||
# filter: ["{ account_id: { _eq: $account_id } }"]
|
|
10
demo
10
demo
@ -1,13 +1,13 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
|
|
||||||
if [ "$1" == "start" ]; then
|
if [ "$1" == "start" ]; then
|
||||||
echo "Downloading pre-built docker images"
|
echo "Downloading pre-built docker images"
|
||||||
docker-compose -f rails-app/demo.yml pull
|
docker-compose -f examples/rails-app/demo.yml pull
|
||||||
echo "Setting up and deploying Super Graph and the demo Rails app"
|
echo "Setting up and deploying Super Graph and the demo Rails app"
|
||||||
docker-compose -f rails-app/demo.yml run rails_app rake db:create db:migrate db:seed
|
docker-compose -f examples/rails-app/demo.yml run rails_app rake db:create db:migrate db:seed
|
||||||
docker-compose -f rails-app/demo.yml up
|
docker-compose -f examples/rails-app/demo.yml up
|
||||||
elif [ "$1" == "stop" ]; then
|
elif [ "$1" == "stop" ]; then
|
||||||
docker-compose -f rails-app/demo.yml down
|
docker-compose -f examples/rails-app/demo.yml down
|
||||||
else
|
else
|
||||||
echo "./demo [start|stop]"
|
echo "./demo [start|stop]"
|
||||||
fi
|
fi
|
@ -12,10 +12,10 @@ services:
|
|||||||
# - "6379:6379"
|
# - "6379:6379"
|
||||||
|
|
||||||
rails_app:
|
rails_app:
|
||||||
build: rails-app/.
|
build: examples/rails-app/.
|
||||||
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
|
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
|
||||||
volumes:
|
volumes:
|
||||||
- ./rails-app:/app
|
- ./examples/rails-app:/app
|
||||||
- /app/tmp
|
- /app/tmp
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
@ -34,7 +34,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- .:/app
|
- .:/app
|
||||||
working_dir: /app
|
working_dir: /app
|
||||||
command: wu -pattern="*.go" go run main.go serv
|
command: wtc
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
- rails_app
|
- rails_app
|
||||||
|
206
docs/guide.md
206
docs/guide.md
@ -588,7 +588,7 @@ query {
|
|||||||
|
|
||||||
## Mutations
|
## Mutations
|
||||||
|
|
||||||
In GraphQL mutations is the operation type for when you need to modify data. Super Graph supports the `insert`, `update` and `delete` database operations. Here are some examples.
|
In GraphQL mutations is the operation type for when you need to modify data. Super Graph supports the `insert`, `update`, `upsert` and `delete` database operations. Here are some examples.
|
||||||
|
|
||||||
When using mutations the data must be passed as variables since Super Graphs compiles the query into an prepared statement in the database for maximum speed. Prepared statements are are functions in your code when called they accept arguments and your variables are passed in as those arguments.
|
When using mutations the data must be passed as variables since Super Graphs compiles the query into an prepared statement in the database for maximum speed. Prepared statements are are functions in your code when called they accept arguments and your variables are passed in as those arguments.
|
||||||
|
|
||||||
@ -721,6 +721,56 @@ mutation {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Upsert
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"id": 5,
|
||||||
|
"name": "Art of Computer Programming",
|
||||||
|
"description": "The Art of Computer Programming (TAOCP) is a comprehensive monograph written by computer scientist Donald Knuth",
|
||||||
|
"price": 30.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
mutation {
|
||||||
|
product(upsert: $data) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bulk upsert
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": [{
|
||||||
|
"id": 5,
|
||||||
|
"name": "Art of Computer Programming",
|
||||||
|
"description": "The Art of Computer Programming (TAOCP) is a comprehensive monograph written by computer scientist Donald Knuth",
|
||||||
|
"price": 30.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"name": "Compilers: Principles, Techniques, and Tools",
|
||||||
|
"description": "Known to professors, students, and developers worldwide as the 'Dragon Book' is available in a new edition",
|
||||||
|
"price": 93.74
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
mutation {
|
||||||
|
product(upsert: $data) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Using variables
|
### Using variables
|
||||||
|
|
||||||
Variables (`$product_id`) and their values (`"product_id": 5`) can be passed along side the GraphQL query. Using variables makes for better client side code as well as improved server side SQL query caching. The build-in web-ui also supports setting variables. Not having to manipulate your GraphQL query string to insert values into it makes for cleaner
|
Variables (`$product_id`) and their values (`"product_id": 5`) can be passed along side the GraphQL query. Using variables makes for better client side code as well as improved server side SQL query caching. The build-in web-ui also supports setting variables. Not having to manipulate your GraphQL query string to insert values into it makes for cleaner
|
||||||
@ -990,29 +1040,42 @@ Configuration files can either be in YAML or JSON their names are derived from t
|
|||||||
We're tried to ensure that the config file is self documenting and easy to work with.
|
We're tried to ensure that the config file is self documenting and easy to work with.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
# Inherit config from this other config file
|
||||||
|
# so I only need to overwrite some values
|
||||||
|
inherits: base
|
||||||
|
|
||||||
app_name: "Super Graph Development"
|
app_name: "Super Graph Development"
|
||||||
host_port: 0.0.0.0:8080
|
host_port: 0.0.0.0:8080
|
||||||
web_ui: true
|
web_ui: true
|
||||||
debug_level: 1
|
|
||||||
|
|
||||||
# debug, info, warn, error, fatal, panic, disable
|
# debug, info, warn, error, fatal, panic
|
||||||
log_level: "info"
|
log_level: "debug"
|
||||||
|
|
||||||
# Disable this in development to get a list of
|
# Disable this in development to get a list of
|
||||||
# queries used. When enabled super graph
|
# queries used. When enabled super graph
|
||||||
# will only allow queries from this list
|
# will only allow queries from this list
|
||||||
# List saved to ./config/allow.list
|
# List saved to ./config/allow.list
|
||||||
use_allow_list: true
|
use_allow_list: false
|
||||||
|
|
||||||
# Throw a 401 on auth failure for queries that need auth
|
# Throw a 401 on auth failure for queries that need auth
|
||||||
# valid values: always, per_query, never
|
# valid values: always, per_query, never
|
||||||
auth_fail_block: always
|
auth_fail_block: never
|
||||||
|
|
||||||
# Latency tracing for database queries and remote joins
|
# Latency tracing for database queries and remote joins
|
||||||
# the resulting latency information is returned with the
|
# the resulting latency information is returned with the
|
||||||
# response
|
# response
|
||||||
enable_tracing: true
|
enable_tracing: true
|
||||||
|
|
||||||
|
# Watch the config folder and reload Super Graph
|
||||||
|
# with the new configs when a change is detected
|
||||||
|
reload_on_config_change: true
|
||||||
|
|
||||||
|
# File that points to the database seeding script
|
||||||
|
# seed_file: seed.js
|
||||||
|
|
||||||
|
# Path pointing to where the migrations can be found
|
||||||
|
migrations_path: ./config/migrations
|
||||||
|
|
||||||
# Postgres related environment Variables
|
# Postgres related environment Variables
|
||||||
# SG_DATABASE_HOST
|
# SG_DATABASE_HOST
|
||||||
# SG_DATABASE_PORT
|
# SG_DATABASE_PORT
|
||||||
@ -1036,7 +1099,7 @@ auth:
|
|||||||
|
|
||||||
# Comment this out if you want to disable setting
|
# Comment this out if you want to disable setting
|
||||||
# the user_id via a header. Good for testing
|
# the user_id via a header. Good for testing
|
||||||
header: X-User-ID
|
creds_in_header: true
|
||||||
|
|
||||||
rails:
|
rails:
|
||||||
# Rails version this is used for reading the
|
# Rails version this is used for reading the
|
||||||
@ -1047,10 +1110,10 @@ auth:
|
|||||||
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://redis:6379
|
||||||
# password: test
|
# password: ""
|
||||||
# max_idle: 80,
|
# max_idle: 80
|
||||||
# max_active: 12000,
|
# max_active: 12000
|
||||||
|
|
||||||
# In most cases you don't need these
|
# In most cases you don't need these
|
||||||
# salt: "encrypted cookie"
|
# salt: "encrypted cookie"
|
||||||
@ -1070,20 +1133,23 @@ database:
|
|||||||
dbname: app_development
|
dbname: app_development
|
||||||
user: postgres
|
user: postgres
|
||||||
password: ''
|
password: ''
|
||||||
# pool_size: 10
|
|
||||||
# max_retries: 0
|
#schema: "public"
|
||||||
# log_level: "debug"
|
#pool_size: 10
|
||||||
|
#max_retries: 0
|
||||||
|
#log_level: "debug"
|
||||||
|
|
||||||
# Define variables here that you want to use in filters
|
# Define variables here that you want to use in filters
|
||||||
|
# sub-queries must be wrapped in ()
|
||||||
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 } }"]
|
# filters: ["{ user_id: { eq: $user_id } }"]
|
||||||
|
|
||||||
# Field and table names that you wish to block
|
# Field and table names that you wish to block
|
||||||
blacklist:
|
blocklist:
|
||||||
- ar_internal_metadata
|
- ar_internal_metadata
|
||||||
- schema_migrations
|
- schema_migrations
|
||||||
- secret
|
- secret
|
||||||
@ -1091,43 +1157,85 @@ database:
|
|||||||
- encrypted
|
- encrypted
|
||||||
- token
|
- token
|
||||||
|
|
||||||
tables:
|
tables:
|
||||||
- name: users
|
- name: customers
|
||||||
# This filter will overwrite defaults.filter
|
remotes:
|
||||||
filter: ["{ id: { eq: $user_id } }"]
|
- name: payments
|
||||||
|
id: stripe_id
|
||||||
|
url: http://rails_app:3000/stripe/$id
|
||||||
|
path: data
|
||||||
|
# debug: true
|
||||||
|
pass_headers:
|
||||||
|
- cookie
|
||||||
|
set_headers:
|
||||||
|
- name: Host
|
||||||
|
value: 0.0.0.0
|
||||||
|
# - name: Authorization
|
||||||
|
# value: Bearer <stripe_api_key>
|
||||||
|
|
||||||
- name: products
|
- # You can create new fields that have a
|
||||||
# Multiple filters are AND'd together
|
# real db table backing them
|
||||||
filter: [
|
name: me
|
||||||
"{ price: { gt: 0 } }",
|
table: users
|
||||||
"{ price: { lt: 8 } }"
|
|
||||||
]
|
|
||||||
|
|
||||||
- name: customers
|
roles_query: "SELECT * FROM users as usr WHERE id = $user_id"
|
||||||
# No filter is used for this field not
|
|
||||||
# even defaults.filter
|
|
||||||
filter: none
|
|
||||||
|
|
||||||
remotes:
|
roles:
|
||||||
- name: payments
|
- name: anon
|
||||||
id: stripe_id
|
tables:
|
||||||
url: http://rails_app:3000/stripe/$id
|
- name: products
|
||||||
path: data
|
limit: 10
|
||||||
# pass_headers:
|
|
||||||
# - cookie
|
|
||||||
# - host
|
|
||||||
set_headers:
|
|
||||||
- name: Authorization
|
|
||||||
value: Bearer <stripe_api_key>
|
|
||||||
|
|
||||||
- # You can create new fields that have a
|
query:
|
||||||
# real db table backing them
|
columns: ["id", "name", "description" ]
|
||||||
name: me
|
aggregation: false
|
||||||
table: users
|
|
||||||
filter: ["{ id: { eq: $user_id } }"]
|
insert:
|
||||||
|
allow: false
|
||||||
|
|
||||||
|
update:
|
||||||
|
allow: false
|
||||||
|
|
||||||
|
delete:
|
||||||
|
allow: false
|
||||||
|
|
||||||
|
- name: user
|
||||||
|
tables:
|
||||||
|
- name: users
|
||||||
|
query:
|
||||||
|
filters: ["{ id: { _eq: $user_id } }"]
|
||||||
|
|
||||||
|
- name: products
|
||||||
|
query:
|
||||||
|
limit: 50
|
||||||
|
filters: ["{ user_id: { eq: $user_id } }"]
|
||||||
|
columns: ["id", "name", "description" ]
|
||||||
|
disable_functions: false
|
||||||
|
|
||||||
|
insert:
|
||||||
|
filters: ["{ user_id: { eq: $user_id } }"]
|
||||||
|
columns: ["id", "name", "description" ]
|
||||||
|
set:
|
||||||
|
- created_at: "now"
|
||||||
|
|
||||||
|
update:
|
||||||
|
filters: ["{ user_id: { eq: $user_id } }"]
|
||||||
|
columns:
|
||||||
|
- id
|
||||||
|
- name
|
||||||
|
set:
|
||||||
|
- updated_at: "now"
|
||||||
|
|
||||||
|
delete:
|
||||||
|
deny: true
|
||||||
|
|
||||||
|
- name: admin
|
||||||
|
match: id = 1
|
||||||
|
tables:
|
||||||
|
- name: users
|
||||||
|
# query:
|
||||||
|
# filters: ["{ account_id: { _eq: $account_id } }"]
|
||||||
|
|
||||||
# - name: posts
|
|
||||||
# filter: ["{ account_id: { _eq: $account_id } }"]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If deploying into environments like Kubernetes it's useful to be able to configure things like secrets and hosts though environment variables therfore we expose the below environment variables. This is escpecially useful for secrets since they are usually injected in via a secrets management framework ie. Kubernetes Secrets
|
If deploying into environments like Kubernetes it's useful to be able to configure things like secrets and hosts though environment variables therfore we expose the below environment variables. This is escpecially useful for secrets since they are usually injected in via a secrets management framework ie. Kubernetes Secrets
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
GIT
|
GIT
|
||||||
remote: https://github.com/stympy/faker.git
|
remote: https://github.com/stympy/faker.git
|
||||||
revision: e7c898c05306409cedf5b795a622a326ec87e279
|
revision: 4e9144825fcc9ba5c83cc0fd037779ab82f3120b
|
||||||
branch: master
|
branch: master
|
||||||
specs:
|
specs:
|
||||||
faker (2.5.0)
|
faker (2.6.0)
|
||||||
i18n (~> 1.6.0)
|
i18n (>= 1.6, < 1.8)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
@ -82,8 +82,7 @@ GEM
|
|||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
regexp_parser (~> 1.5)
|
regexp_parser (~> 1.5)
|
||||||
xpath (~> 3.2)
|
xpath (~> 3.2)
|
||||||
childprocess (2.0.0)
|
childprocess (3.0.0)
|
||||||
rake (< 13.0)
|
|
||||||
chromedriver-helper (2.1.1)
|
chromedriver-helper (2.1.1)
|
||||||
archive-zip (~> 0.10)
|
archive-zip (~> 0.10)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
@ -107,7 +106,7 @@ GEM
|
|||||||
ffi (1.11.1)
|
ffi (1.11.1)
|
||||||
globalid (0.4.2)
|
globalid (0.4.2)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
i18n (1.6.0)
|
i18n (1.7.0)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
io-like (0.3.0)
|
io-like (0.3.0)
|
||||||
jbuilder (2.9.1)
|
jbuilder (2.9.1)
|
||||||
@ -157,15 +156,15 @@ GEM
|
|||||||
rails-dom-testing (2.0.3)
|
rails-dom-testing (2.0.3)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
rails-html-sanitizer (1.2.0)
|
rails-html-sanitizer (1.3.0)
|
||||||
loofah (~> 2.2, >= 2.2.2)
|
loofah (~> 2.3)
|
||||||
railties (6.0.0)
|
railties (6.0.0)
|
||||||
actionpack (= 6.0.0)
|
actionpack (= 6.0.0)
|
||||||
activesupport (= 6.0.0)
|
activesupport (= 6.0.0)
|
||||||
method_source
|
method_source
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.20.3, < 2.0)
|
thor (>= 0.20.3, < 2.0)
|
||||||
rake (12.3.3)
|
rake (13.0.0)
|
||||||
rb-fsevent (0.10.3)
|
rb-fsevent (0.10.3)
|
||||||
rb-inotify (0.10.0)
|
rb-inotify (0.10.0)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
@ -203,8 +202,8 @@ GEM
|
|||||||
sprockets (>= 2.8, < 4.0)
|
sprockets (>= 2.8, < 4.0)
|
||||||
sprockets-rails (>= 2.0, < 4.0)
|
sprockets-rails (>= 2.0, < 4.0)
|
||||||
tilt (>= 1.1, < 3)
|
tilt (>= 1.1, < 3)
|
||||||
selenium-webdriver (3.142.5)
|
selenium-webdriver (3.142.6)
|
||||||
childprocess (>= 0.5, < 3.0)
|
childprocess (>= 0.5, < 4.0)
|
||||||
rubyzip (>= 1.2.2)
|
rubyzip (>= 1.2.2)
|
||||||
spring (2.1.0)
|
spring (2.1.0)
|
||||||
spring-watcher-listen (2.0.1)
|
spring-watcher-listen (2.0.1)
|
||||||
@ -239,7 +238,7 @@ GEM
|
|||||||
websocket-extensions (0.1.4)
|
websocket-extensions (0.1.4)
|
||||||
xpath (3.2.0)
|
xpath (3.2.0)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
zeitwerk (2.1.10)
|
zeitwerk (2.2.0)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user