Refactor Super Graph into a library #26
@ -1,267 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<main aria-labelledby="main-title" >
|
||||
<Navbar />
|
||||
|
||||
<div class="container mx-auto">
|
||||
<div class="flex flex-col md:flex-row justify-between px-10 md:px-20">
|
||||
<div class="bg-bottom bg-no-repeat bg-cover">
|
||||
<div class="text-center md:text-left pt-24">
|
||||
<h1 v-if="data.heroText !== null" class="text-5xl font-bold text-black pb-0 uppercase">
|
||||
<img src="/super-graph.png" width="250" />
|
||||
</h1>
|
||||
|
||||
<p class="text-4xl text-gray-800 leading-tight mt-1">
|
||||
Build web products faster. Secure high performance GraphQL
|
||||
</p>
|
||||
|
||||
<NavLink
|
||||
class="inline-block px-4 py-3 my-8 bg-blue-600 text-blue-100 font-bold rounded"
|
||||
:item="actionLink"
|
||||
/>
|
||||
|
||||
<a
|
||||
class="px-4 py-3 my-8 border-2 border-gray-500 text-gray-600 font-bold rounded"
|
||||
href="https://github.com/dosco/super-graph"
|
||||
target="_blank"
|
||||
>Github</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="py-10 md:p-20">
|
||||
<img src="/hologram.svg" class="h-64">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div
|
||||
class="flex flex-wrap mx-2 md:mx-20"
|
||||
v-if="data.features && data.features.length"
|
||||
>
|
||||
<div
|
||||
class="w-2/4 md:w-1/3 shadow"
|
||||
v-for="(feature, index) in data.features"
|
||||
:key="index"
|
||||
>
|
||||
<div class="p-8">
|
||||
<h2 class="md:text-xl text-blue-800 font-medium border-0 mb-1">{{ feature.title }}</h2>
|
||||
<p class="md:text-xl text-gray-700 leading-snug">{{ feature.details }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="bg-gray-100 mt-10">
|
||||
<div class="container mx-auto px-10 md:px-0 py-32">
|
||||
|
||||
<div class="pb-8 hidden md:block ">
|
||||
<img src="arch-basic.svg">
|
||||
</div>
|
||||
|
||||
<h1 class="uppercase font-semibold text-xl text-blue-800 mb-4">
|
||||
What is {{ data.heroText }}?
|
||||
</h1>
|
||||
<div class="text-2xl md:text-3xl">
|
||||
Super Graph can automatically learn a Postgres database and instantly serve it as a fast and secured GraphQL API. It comes with tools to create a new app and manage it's database. You get it all, a very productive developer and a highly scalable app backend. It's designed to work well on serverless platforms by Google, AWS, Microsoft, etc. The goal is to save you a ton of time and money so you can focus on you're apps core value.
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="flex flex-wrap">
|
||||
<div class="md:w-2/4">
|
||||
<img src="/graphql.png">
|
||||
</div>
|
||||
|
||||
<div class="md:w-2/4">
|
||||
<img src="/json.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-10 py-10 md:py-20">
|
||||
<div class="container mx-auto px-10 md:px-0">
|
||||
<h1 class="uppercase font-semibold text-xl text-blue-800 mb-4">
|
||||
How to use {{ data.heroText }}?
|
||||
</h1>
|
||||
<div class="text-2xl md:text-3xl">
|
||||
<small class="text-sm">Use the below command to download and install Super Graph. You will need Go 1.13 or above</small>
|
||||
<pre>‣ GO111MODULE=on go get -u github.com/dosco/super-graph</pre>
|
||||
|
||||
<small class="text-sm">Create a new app and change to it's directory</small>
|
||||
<pre>‣ super-graph new blog; cd blog</pre>
|
||||
|
||||
<small class="text-sm">Setup the app database and seed it with fake data. Docker compose will start a Postgres database for your app</small>
|
||||
<pre>‣ docker-compose run blog_api ./super-graph db:setup</pre>
|
||||
|
||||
<small class="text-sm">And finally launch Super Graph configured for your app</small>
|
||||
<pre>‣ docker-compose up</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-100 mt-10">
|
||||
<div class="container mx-auto px-10 md:px-0 py-32">
|
||||
<h1 class="uppercase font-semibold text-xl text-blue-800 mb-4">
|
||||
The story of {{ data.heroText }}
|
||||
</h1>
|
||||
<div class="text-2xl md:text-3xl">
|
||||
After working on several products through my career I find that we spend way too much time on building API backends. Most APIs also require constant updating, this costs real time and money.<br><br>
|
||||
|
||||
It's always the same thing, figure out what the UI needs then build an endpoint for it. Most API code involves struggling with an ORM to query a database and mangle the data into a shape that the UI expects to see.<br><br>
|
||||
|
||||
I didn't want to write this code anymore, I wanted the computer to do it. Enter GraphQL, to me it sounded great, but it still required me to write all the same database query code.<br><br>
|
||||
|
||||
Having worked with compilers before I saw this as a compiler problem. Why not build a compiler that converts GraphQL to highly efficient SQL.<br><br>
|
||||
|
||||
This compiler is what sits at the heart of Super Graph with layers of useful functionality around it like authentication, remote joins, rails integration, database migrations and everything else needed for you to build production ready apps with it.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overflow-hidden bg-indigo-900">
|
||||
<div class="container mx-auto py-20">
|
||||
<img src="/super-graph-web-ui.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="py-10 md:py-20">
|
||||
<div class="container mx-auto px-10 md:px-0">
|
||||
<h1 class="uppercase font-semibold text-xl text-blue-800 mb-4">
|
||||
Try it with a demo Rails app
|
||||
</h1>
|
||||
<div class="text-2xl md:text-3xl">
|
||||
<small class="text-sm">Download the Docker compose config for the demo</small>
|
||||
<pre>‣ curl -L -o demo.yml https://bit.ly/2FZS0uw</pre>
|
||||
|
||||
<small class="text-sm">Setup the demo database</small>
|
||||
<pre>‣ docker-compose -f demo.yml run rails_app rake db:create db:migrate db:seed</pre>
|
||||
|
||||
<small class="text-sm">Run the demo</small>
|
||||
<pre>‣ docker-compose -f demo.yml up</pre>
|
||||
|
||||
<small class="text-sm">Signin to the demo app (user1@demo.com / 123456)</small>
|
||||
<pre>‣ open http://localhost:3000</pre>
|
||||
|
||||
<small class="text-sm">Try the super graph web ui</small>
|
||||
<pre>‣ open http://localhost:8080</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border-t py-10">
|
||||
<div class="block md:hidden w-100">
|
||||
<iframe src='https://www.youtube.com/embed/MfPL2A-DAJk' frameborder='0' allowfullscreen style="width: 100%; height: 250px;">
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
<div class="container mx-auto flex flex-col md:flex-row items-center">
|
||||
<div class="w-100 md:w-1/2 p-8">
|
||||
<h1 class="text-2xl font-bold">GraphQL the future of APIs</h1>
|
||||
<p class="text-xl text-gray-600">Keeping a tight and fast development loop helps you iterate quickly. Leveraging technology like Super Graph focuses your team on building the core product and not reinventing wheels. GraphQL eliminate the dependency on the backend engineering and keeps the things moving fast</p>
|
||||
</div>
|
||||
|
||||
<div class="hidden md:block md:w-1/2">
|
||||
<style>.embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }</style>
|
||||
<div class="embed-container shadow">
|
||||
<iframe src='https://www.youtube.com/embed/MfPL2A-DAJk' frameborder='0' allowfullscreen >
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-200 mt-10">
|
||||
<div class="container mx-auto px-10 md:px-0 py-32">
|
||||
<h1 class="uppercase font-semibold text-xl text-blue-800 mb-4">
|
||||
Build Secure Apps
|
||||
</h1>
|
||||
<div class="flex flex-col text-2xl md:text-3xl">
|
||||
<card className="mb-1 p-8">
|
||||
<template #image><font-awesome-icon icon="portrait" class="text-red-500" /></template>
|
||||
<template #title>Role Based Access Control</template>
|
||||
<template #body>Dynamically assign roles like admin, manager or anon to specific users. Generate role specific queries at runtime. For example admins can get all users while others can only fetch their own user.</template>
|
||||
</card>
|
||||
<card className="mb-1 p-8">
|
||||
<template #image><font-awesome-icon icon="shield-alt" class="text-blue-500" /></template>
|
||||
<template #title>Prepared Statements</template>
|
||||
<template #body>An additional layer of protection from a variety of security issues like SQL injection. In production mode all queries are precompiled into prepared statements so only those can be executed. This also significantly speeds up all queries.</template>
|
||||
</card>
|
||||
<card className="p-8">
|
||||
<template #image><font-awesome-icon icon="lock" class="text-green-500"/></template>
|
||||
<template #title>Fuzz Tested Code</template>
|
||||
<template #body>Fuzzing is done by complex software that generates massives amounts of random input to detect if code is free of security bugs. Google uses fuzzing to protects everything from their cloud infrastructure to the Chrome browser.</template>
|
||||
</card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="">
|
||||
<div class="container mx-auto px-10 md:px-0 py-32">
|
||||
<h1 class="uppercase font-semibold text-xl text-blue-800 mb-4">
|
||||
More Features
|
||||
</h1>
|
||||
<div class="flex flex-col md:flex-row text-2xl md:text-3xl">
|
||||
<card className="mr-0 md:mr-1 mb-1 flex-col w-100 md:w-1/3 items-center">
|
||||
<template #image><img src="/arch-remote-join.svg" class="h-64"></template>
|
||||
<template #title>Remote Joins</template>
|
||||
<template #body>A powerful feature that allows you to query your database and remote REST APIs at the same time. For example fetch a user from the DB, his tweets from Twitter and his payments from Stripe with a single GraphQL query.</template>
|
||||
</card>
|
||||
<card className="mr-0 md:mr-1 mb-1 flex-col w-100 md:w-1/3">
|
||||
<template #image><img src="/arch-search.svg" class="h-64"></template>
|
||||
<template #title>Full Text Search</template>
|
||||
<template #body>Postgres has excellent full-text search built-in. You don't need another expensive service. Super Graph makes it super easy to use with keyword ranking and highlighting also supported.</template>
|
||||
</card>
|
||||
<card className="mb-1 flex-col w-100 md:w-1/3">
|
||||
<template #image><img src="/arch-bulk.svg" class="h-64"></template>
|
||||
<template #title>Bulk Inserts</template>
|
||||
<template #body>Efficiently insert, update and delete multiple items with a single query. Upserts are also supported</template>
|
||||
</card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="mx-auto text-center py-8"
|
||||
v-if="data.footer"
|
||||
>
|
||||
{{ data.footer }}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NavLink from '@theme/components/NavLink.vue'
|
||||
import Navbar from '@theme/components/Navbar.vue'
|
||||
import Card from './Card.vue'
|
||||
|
||||
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import { faPortrait, faShieldAlt, faLock } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
||||
|
||||
library.add(faPortrait, faShieldAlt, faLock)
|
||||
|
||||
export default {
|
||||
components: { NavLink, Navbar, FontAwesomeIcon, Card },
|
||||
|
||||
computed: {
|
||||
data () {
|
||||
return this.$page.frontmatter
|
||||
},
|
||||
|
||||
actionLink () {
|
||||
return {
|
||||
link: this.data.actionLink,
|
||||
text: this.data.actionText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
0
docs/.gitignore → docs/guide/.gitignore
vendored
358
docs/guide/.vuepress/components/HomeLayout.vue
Normal file
@ -0,0 +1,358 @@
|
||||
<template>
|
||||
<div>
|
||||
<main aria-labelledby="main-title" >
|
||||
<Navbar />
|
||||
|
||||
<div class="container mx-auto mt-24">
|
||||
<div class="text-center">
|
||||
<div class="text-center text-4xl text-gray-800 leading-tight">
|
||||
Fetch data without code
|
||||
</div>
|
||||
|
||||
<NavLink
|
||||
class="inline-block px-4 py-3 my-8 bg-blue-600 text-blue-100 font-bold rounded"
|
||||
:item="actionLink"
|
||||
/>
|
||||
|
||||
<a
|
||||
class="px-4 py-3 my-8 border-2 border-gray-500 text-gray-600 font-bold rounded"
|
||||
href="https://github.com/dosco/super-graph"
|
||||
target="_blank"
|
||||
>Github</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container mx-auto mb-8">
|
||||
<div class="flex flex-wrap">
|
||||
<div class="w-100 md:w-1/2 bg-indigo-300 text-indigo-800 text-lg p-4">
|
||||
<div class="text-center text-2xl font-bold pb-2">Before, struggle with SQL</div>
|
||||
<pre>
|
||||
|
||||
type User struct {
|
||||
gorm.Model
|
||||
Profile Profile
|
||||
ProfileID int
|
||||
}
|
||||
|
||||
type Profile struct {
|
||||
gorm.Model
|
||||
Name string
|
||||
}
|
||||
|
||||
db.Model(&user).
|
||||
Related(&profile).
|
||||
Association("Languages").
|
||||
Where("name in (?)", []string{"test"}).
|
||||
Joins("left join emails on emails.user_id = users.id")
|
||||
Find(&users)
|
||||
|
||||
and more ...
|
||||
</pre>
|
||||
</div>
|
||||
<div class="w-100 md:w-1/2 bg-green-300 text-black text-lg p-4">
|
||||
<div class="text-center text-2xl font-bold pb-2">With Super Graph, just ask.</div>
|
||||
<pre>
|
||||
query {
|
||||
user(id: 5) {
|
||||
id
|
||||
first_name
|
||||
last_name
|
||||
picture_url
|
||||
}
|
||||
posts(first: 20, order_by: { score: desc }) {
|
||||
slug
|
||||
title
|
||||
created_at
|
||||
cached_votes_total
|
||||
vote(where: { user_id: { eq: $user_id } }) {
|
||||
id
|
||||
}
|
||||
author { id name }
|
||||
tags { id name }
|
||||
}
|
||||
posts_cursor
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div
|
||||
class="flex flex-wrap mx-2 md:mx-20"
|
||||
v-if="data.features && data.features.length"
|
||||
>
|
||||
<div
|
||||
class="w-2/4 md:w-1/3 shadow"
|
||||
v-for="(feature, index) in data.features"
|
||||
:key="index"
|
||||
>
|
||||
<div class="p-8">
|
||||
<h2 class="md:text-xl text-blue-800 font-medium border-0 mb-1">{{ feature.title }}</h2>
|
||||
<p class="md:text-xl text-gray-700 leading-snug">{{ feature.details }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="bg-gray-100 mt-10">
|
||||
<div class="container mx-auto px-10 md:px-0 py-32">
|
||||
|
||||
<div class="pb-8 hidden md:flex justify-center">
|
||||
<img src="arch-basic.svg">
|
||||
</div>
|
||||
|
||||
<h1 class="uppercase font-semibold text-xl text-blue-800 text-center mb-4">
|
||||
What is Super Graph?
|
||||
</h1>
|
||||
<div class="text-2xl md:text-3xl">
|
||||
Super Graph is a library and service that fetches data from any Postgres database using just GraphQL. No more struggling with ORMs and SQL to wrangle data out of the database. No more having to figure out the right joins or making ineffiient queries. However complex the GraphQL, Super Graph will always generate just one single efficient SQL query. The goal is to save you time and money so you can focus on you're apps core value.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="container mx-auto flex flex-wrap">
|
||||
<div class="md:w-1/2">
|
||||
<img src="/graphql.png">
|
||||
</div>
|
||||
|
||||
<div class="md:w-1/2">
|
||||
<img src="/json.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-10 py-10 md:py-20">
|
||||
<div class="container mx-auto px-10 md:px-0">
|
||||
<h1 class="uppercase font-semibold text-2xl text-blue-800 text-center">
|
||||
Try Super Graph
|
||||
</h1>
|
||||
|
||||
<h1 class="uppercase font-semibold text-lg text-gray-800">
|
||||
Deploy as a service using docker
|
||||
</h1>
|
||||
<div class="bg-gray-800 text-indigo-300 p-4 rounded">
|
||||
<pre>$ git clone https://github.com/dosco/super-graph && cd super-graph && make install</pre>
|
||||
<pre>$ super-graph new blog; cd blog</pre>
|
||||
<pre>$ docker-compose run blog_api ./super-graph db:setup</pre>
|
||||
<pre>$ docker-compose up</pre>
|
||||
</div>
|
||||
|
||||
<div class="border-t mt-4 pb-4"></div>
|
||||
|
||||
<h1 class="uppercase font-semibold text-lg text-gray-800">
|
||||
Or use it with your own code
|
||||
</h1>
|
||||
<div class="text-md">
|
||||
<pre class="bg-gray-800 text-indigo-300 p-4 rounded">
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/dosco/super-graph/config"
|
||||
"github.com/dosco/super-graph/core"
|
||||
_ "github.com/jackc/pgx/v4/stdlib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("pgx", "postgres://postgrs:@localhost:5432/example_db")
|
||||
if err != nil {
|
||||
log.Fatalf(err)
|
||||
}
|
||||
|
||||
conf, err := config.NewConfig("./config")
|
||||
if err != nil {
|
||||
log.Fatalf(err)
|
||||
}
|
||||
|
||||
sg, err = core.NewSuperGraph(conf, db)
|
||||
if err != nil {
|
||||
log.Fatalf(err)
|
||||
}
|
||||
|
||||
graphqlQuery := `
|
||||
query {
|
||||
posts {
|
||||
id
|
||||
title
|
||||
}
|
||||
}`
|
||||
|
||||
res, err := sg.GraphQL(context.Background(), graphqlQuery, nil)
|
||||
if err != nil {
|
||||
log.Fatalf(err)
|
||||
}
|
||||
|
||||
fmt.Println(string(res.Data))
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-100 mt-10">
|
||||
<div class="container mx-auto px-10 md:px-0 py-32">
|
||||
<h1 class="uppercase font-semibold text-xl text-blue-800 mb-4">
|
||||
The story of {{ data.heroText }}
|
||||
</h1>
|
||||
<div class="text-2xl md:text-3xl">
|
||||
After working on several products through my career I find that we spend way too much time on building API backends. Most APIs also require constant updating, this costs real time and money.<br><br>
|
||||
|
||||
It's always the same thing, figure out what the UI needs then build an endpoint for it. Most API code involves struggling with an ORM to query a database and mangle the data into a shape that the UI expects to see.<br><br>
|
||||
|
||||
I didn't want to write this code anymore, I wanted the computer to do it. Enter GraphQL, to me it sounded great, but it still required me to write all the same database query code.<br><br>
|
||||
|
||||
Having worked with compilers before I saw this as a compiler problem. Why not build a compiler that converts GraphQL to highly efficient SQL.<br><br>
|
||||
|
||||
This compiler is what sits at the heart of Super Graph with layers of useful functionality around it like authentication, remote joins, rails integration, database migrations and everything else needed for you to build production ready apps with it.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overflow-hidden bg-indigo-900">
|
||||
<div class="container mx-auto py-20">
|
||||
<img src="/super-graph-web-ui.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="py-10 md:py-20">
|
||||
<div class="container mx-auto px-10 md:px-0">
|
||||
<h1 class="uppercase font-semibold text-xl text-blue-800 mb-4">
|
||||
Try it with a demo Rails app
|
||||
</h1>
|
||||
<div class="text-2xl md:text-3xl">
|
||||
<small class="text-sm">Download the Docker compose config for the demo</small>
|
||||
<pre>‣ curl -L -o demo.yml https://bit.ly/2FZS0uw</pre>
|
||||
|
||||
<small class="text-sm">Setup the demo database</small>
|
||||
<pre>‣ docker-compose -f demo.yml run rails_app rake db:create db:migrate db:seed</pre>
|
||||
|
||||
<small class="text-sm">Run the demo</small>
|
||||
<pre>‣ docker-compose -f demo.yml up</pre>
|
||||
|
||||
<small class="text-sm">Signin to the demo app (user1@demo.com / 123456)</small>
|
||||
<pre>‣ open http://localhost:3000</pre>
|
||||
|
||||
<small class="text-sm">Try the super graph web ui</small>
|
||||
<pre>‣ open http://localhost:8080</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="border-t py-10">
|
||||
<div class="block md:hidden w-100">
|
||||
<iframe src='https://www.youtube.com/embed/MfPL2A-DAJk' frameborder='0' allowfullscreen style="width: 100%; height: 250px;">
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
<div class="container mx-auto flex flex-col md:flex-row items-center">
|
||||
<div class="w-100 md:w-1/2 p-8">
|
||||
<h1 class="text-2xl font-bold">GraphQL the future of APIs</h1>
|
||||
<p class="text-xl text-gray-600">Keeping a tight and fast development loop helps you iterate quickly. Leveraging technology like Super Graph focuses your team on building the core product and not reinventing wheels. GraphQL eliminate the dependency on the backend engineering and keeps the things moving fast</p>
|
||||
</div>
|
||||
|
||||
<div class="hidden md:block md:w-1/2">
|
||||
<style>.embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }</style>
|
||||
<div class="embed-container shadow">
|
||||
<iframe src='https://www.youtube.com/embed/MfPL2A-DAJk' frameborder='0' allowfullscreen >
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-200 mt-10">
|
||||
<div class="container mx-auto px-10 md:px-0 py-32">
|
||||
<h1 class="uppercase font-semibold text-xl text-blue-800 mb-4">
|
||||
Build Secure Apps
|
||||
</h1>
|
||||
<div class="flex flex-col text-2xl md:text-3xl">
|
||||
<card className="mb-1 p-8">
|
||||
<template #image><font-awesome-icon icon="portrait" class="text-red-500" /></template>
|
||||
<template #title>Role Based Access Control</template>
|
||||
<template #body>Dynamically assign roles like admin, manager or anon to specific users. Generate role specific queries at runtime. For example admins can get all users while others can only fetch their own user.</template>
|
||||
</card>
|
||||
<card className="mb-1 p-8">
|
||||
<template #image><font-awesome-icon icon="shield-alt" class="text-blue-500" /></template>
|
||||
<template #title>Prepared Statements</template>
|
||||
<template #body>An additional layer of protection from a variety of security issues like SQL injection. In production mode all queries are precompiled into prepared statements so only those can be executed. This also significantly speeds up all queries.</template>
|
||||
</card>
|
||||
<card className="p-8">
|
||||
<template #image><font-awesome-icon icon="lock" class="text-green-500"/></template>
|
||||
<template #title>Fuzz Tested Code</template>
|
||||
<template #body>Fuzzing is done by complex software that generates massives amounts of random input to detect if code is free of security bugs. Google uses fuzzing to protects everything from their cloud infrastructure to the Chrome browser.</template>
|
||||
</card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="">
|
||||
<div class="container mx-auto px-10 md:px-0 py-32">
|
||||
<h1 class="uppercase font-semibold text-xl text-blue-800 mb-4">
|
||||
More Features
|
||||
</h1>
|
||||
<div class="flex flex-col md:flex-row text-2xl md:text-3xl">
|
||||
<card className="mr-0 md:mr-1 mb-1 flex-col w-100 md:w-1/3 items-center">
|
||||
<!-- <template #image><img src="/arch-remote-join.svg" class="h-64"></template> -->
|
||||
<template #title>Remote Joins</template>
|
||||
<template #body>A powerful feature that allows you to query your database and remote REST APIs at the same time. For example fetch a user from the DB, his tweets from Twitter and his payments from Stripe with a single GraphQL query.</template>
|
||||
</card>
|
||||
<card className="mr-0 md:mr-1 mb-1 flex-col w-100 md:w-1/3">
|
||||
<!-- <template #image><img src="/arch-search.svg" class="h-64"></template> -->
|
||||
<template #title>Full Text Search</template>
|
||||
<template #body>Postgres has excellent full-text search built-in. You don't need another expensive service. Super Graph makes it super easy to use with keyword ranking and highlighting also supported.</template>
|
||||
</card>
|
||||
<card className="mb-1 flex-col w-100 md:w-1/3">
|
||||
<!-- <template #image><img src="/arch-bulk.svg" class="h-64"></template> -->
|
||||
<template #title>Bulk Inserts</template>
|
||||
<template #body>Efficiently insert, update and delete multiple items with a single query. Upserts are also supported</template>
|
||||
</card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="mx-auto text-center py-8"
|
||||
v-if="data.footer"
|
||||
>
|
||||
{{ data.footer }}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NavLink from '@theme/components/NavLink.vue'
|
||||
import Navbar from '@theme/components/Navbar.vue'
|
||||
import Card from './Card.vue'
|
||||
|
||||
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import { faPortrait, faShieldAlt, faLock } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
||||
|
||||
library.add(faPortrait, faShieldAlt, faLock)
|
||||
|
||||
export default {
|
||||
components: { NavLink, Navbar, FontAwesomeIcon, Card },
|
||||
|
||||
computed: {
|
||||
data () {
|
||||
return this.$page.frontmatter
|
||||
},
|
||||
|
||||
actionLink () {
|
||||
return {
|
||||
link: this.data.actionLink,
|
||||
text: this.data.actionText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,6 +1,6 @@
|
||||
let ogprefix = 'og: http://ogp.me/ns#'
|
||||
let title = 'Super Graph'
|
||||
let description = 'An instant GraphQL API for your app. No code needed.'
|
||||
let description = 'Fetch data without code'
|
||||
let color = '#f42525'
|
||||
|
||||
module.exports = {
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 146 KiB |
Before Width: | Height: | Size: 911 KiB After Width: | Height: | Size: 911 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
@ -19,8 +19,8 @@ features:
|
||||
details: Compiles your GraphQL into a fast SQL query in realtime.
|
||||
- title: Built in GO
|
||||
details: Built in Go is a language created at Google to build fast and secure web services.
|
||||
- title: Ruby-on-Rails
|
||||
details: Can read Rails cookies and supports rails database conventions.
|
||||
- title: In your own Code
|
||||
details: Use as a library in your own GO code. Build faster save time and money.
|
||||
- title: Serverless
|
||||
details: Instant startup for scale to zero environments like Google Cloud Run, App Engine, AWS Lambda
|
||||
- title: Free and Open Source
|
@ -1676,7 +1676,7 @@ app_name: "Super Graph Development"
|
||||
host_port: 0.0.0.0:8080
|
||||
web_ui: true
|
||||
|
||||
# debug, info, warn, error, fatal, panic
|
||||
# debug, error, warn, info
|
||||
log_level: "debug"
|
||||
|
||||
# enable or disable http compression (uses gzip)
|
203
docs/slides/highperf.slide
Normal file
@ -0,0 +1,203 @@
|
||||
High Performance Code in GO
|
||||
GoTO, August 2019
|
||||
Tags: GraphQL, API, GoLang, Postgres
|
||||
|
||||
Vikram Rangnekar
|
||||
https://twitter.com/dosco
|
||||
|
||||
* About me
|
||||
|
||||
Co-founder of *movremote.com* a platform to connect developers with Silicon Valley
|
||||
companies hiring remote.
|
||||
|
||||
Previously worked on Platform, Frontend and Ads @ Linkedin building the distributed targeting and serving infrastructure behind Linkedin Ads.
|
||||
|
||||
Also currently building Super Graph an open source instant GraphQL engine for Postgres and Rails. Written in GO
|
||||
|
||||
MOV Remote
|
||||
.link https://movremote.com
|
||||
|
||||
Super Graph
|
||||
.link https://supergraph.dev
|
||||
|
||||
* Why does it matter?
|
||||
|
||||
- Computer are not getting dramatically faster
|
||||
- Our software is getting slower
|
||||
- Demands on our software are increasing
|
||||
- Scale of internet poducts is accelerating
|
||||
- Faster = More money (For you)
|
||||
|
||||
* What does high performance mean?
|
||||
|
||||
- Code that runs fast (relative)
|
||||
- Minimizes I/O latency
|
||||
- Efficient in terms of GC
|
||||
|
||||
|
||||
"Premature optimization is the root of all evil (or at least most of it) in programming."
|
||||
-- Donald Knuth
|
||||
|
||||
"Measure twice cut once"
|
||||
-- Someone
|
||||
|
||||
* Code that runs fast
|
||||
|
||||
1. Algorithm choices
|
||||
2. Rewrite in GO
|
||||
3. Reuse Memory
|
||||
4. Parallelize I/O
|
||||
4. Keep it simple
|
||||
|
||||
* Benchmarking
|
||||
|
||||
* $ benchcmp bench.1 bench.2
|
||||
|
||||
.image https://pbs.twimg.com/media/D8_uRFWU0AUdWkM?format=jpg&name=large _ 970
|
||||
|
||||
* Howto benchmark
|
||||
|
||||
Single threaded
|
||||
|
||||
func BenchmarkYourFunc(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
_, err := yourFunction(data)
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
Parallel
|
||||
|
||||
func BenchmarkYourFuncP(b *testing.B) {
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, err := yourFunction(data)
|
||||
...
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
* Profileing Your Code
|
||||
|
||||
go test -bench=. -benchmem -memprofile mem.out -run=XXX
|
||||
go tool pprof -cum mem.out
|
||||
|
||||
Get a nice command line
|
||||
|
||||
pkg: github.com/dosco/super-graph/psql
|
||||
BenchmarkCompile-8 100000 15138 ns/op 3553 B/op 35 allocs/op
|
||||
BenchmarkCompileParallel-8 300000 4760 ns/op 3583 B/op 35 allocs/op
|
||||
PASS
|
||||
ok github.com/dosco/super-graph/psql 3.174s
|
||||
Type: alloc_space
|
||||
Time: Aug 21, 2019 at 11:56am (EDT)
|
||||
Entering interactive mode (type "help" for commands, "o" for options)
|
||||
(pprof)
|
||||
|
||||
Powerful commands
|
||||
|
||||
top, web, png, pdf, ... and more
|
||||
|
||||
* Top - Shows you the top allocating functions
|
||||
|
||||
(pprof) top
|
||||
Showing nodes accounting for 1.07GB, 77.92% of 1.37GB total
|
||||
Showing top 10 nodes out of 34
|
||||
flat flat% sum% cum cum%
|
||||
0.01GB 0.89% 0.89% 1.11GB 80.77% github.com/[...]/qcode.(*Compiler).Compile
|
||||
0 0% 0.89% 1.02GB 74.22% github.com/dosco/super-graph/
|
||||
0.52GB 37.74% 38.63% 0.94GB 68.50% github.com/[...]/qcode.(*Compiler).compileQuery
|
||||
0.54GB 39.29% 77.92% 0.54GB 39.29% github.com/dosco/super-graph/util.NewStack
|
||||
|
||||
Digging deeper
|
||||
|
||||
(pprof) top .compileQuery
|
||||
focus=.compileQuery
|
||||
Showing nodes accounting for 1006.59MB, 69.36% of 1451.18MB total
|
||||
Showing top 10 nodes out of 26
|
||||
flat flat% sum% cum cum%
|
||||
0 0% 0% 1006.05MB 69.33% github.com/[...]/qcode.(*Compiler).Compile
|
||||
579.44MB 39.93% 39.93% 1006.05MB 69.33% github.com/[...]/qcode.(*Compiler).compileQuery
|
||||
|
||||
* Cool Graphs
|
||||
|
||||
.image https://matoski.com/article/golang-profiling-flamegraphs/cpu-profile-graph-001.png 500 _
|
||||
|
||||
* Reducing Allocations - Part 1
|
||||
|
||||
Pre-allocate
|
||||
|
||||
m := make(map[string]someStruct{}, len(whatever))
|
||||
mp := &m[i]
|
||||
|
||||
Work with bytes if possible
|
||||
|
||||
inlineToLower(&value) instead of bytes.ToLower(value)
|
||||
|
||||
Reuse Memory
|
||||
|
||||
var nodePool = sync.Pool{
|
||||
New: func() interface{} { return new(Node) },
|
||||
}
|
||||
|
||||
Use Builders
|
||||
|
||||
var b strings.Builder
|
||||
b.WriteString("hello ");
|
||||
b.WriteString("world")
|
||||
|
||||
* Reducing Allocations - Part 2
|
||||
|
||||
Use streaming (io.Reader and io.Writer)
|
||||
|
||||
r := strings.NewReader("some io.Reader stream to be read\n")
|
||||
|
||||
_, err := io.Copy(os.Stdout, r);
|
||||
|
||||
Allocate Together
|
||||
|
||||
type Node struct {
|
||||
Children []Child
|
||||
childA [5]Child
|
||||
}
|
||||
n := Node{}
|
||||
n.Children = n.childA[:0]
|
||||
|
||||
Use 'Append' functions
|
||||
|
||||
strconv.AppendInt(b10, 42, 10) instead of strconv.FormatInt(42, 10)
|
||||
|
||||
* Reducing Allocations - Part 3
|
||||
|
||||
Use 'unsafe' if you know what you're doing
|
||||
|
||||
func bytesToString(b []byte) string {
|
||||
return *(*string)(unsafe.Pointer(&b))
|
||||
}
|
||||
|
||||
* Squeezing out more performance
|
||||
|
||||
Avoid reflection use generators
|
||||
|
||||
Inlined Assembly (Crazy)
|
||||
|
||||
// add.go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func add(x, y int64) int64
|
||||
|
||||
func main() {
|
||||
fmt.Println(add(2, 3))
|
||||
}
|
||||
|
||||
// add_amd64.s
|
||||
TEXT ·add(SB),NOSPLIT,$0
|
||||
MOVQ x+0(FP), BX
|
||||
MOVQ y+8(FP), BP
|
||||
ADDQ BP, BX
|
||||
MOVQ BX, ret+16(FP)
|
||||
RET
|
||||
|
101
docs/slides/overview.slide
Normal file
@ -0,0 +1,101 @@
|
||||
Super Graph
|
||||
Instant GraphQL API for Rails. Zero Code.
|
||||
Tags: GraphQL, API, GoLang, Postgres
|
||||
|
||||
Vikram Rangnekar
|
||||
https://twitter.com/dosco
|
||||
|
||||
|
||||
* Motivation
|
||||
|
||||
- Honestly, cause it was more fun than my real work.
|
||||
- Bored of building yet anther CRUD API
|
||||
- Save hours of my life
|
||||
- Easier to use advanced Postgres features
|
||||
- Always get secure, optimized queries
|
||||
- Quickly add GraphQL to existing apps
|
||||
|
||||
* Got Web UI?
|
||||
|
||||
.image https://supergraph.dev/super-graph-web-ui.png _ 1000
|
||||
|
||||
* What does it do?
|
||||
|
||||
- Add a GraphQL API to any Rails app with zero code
|
||||
- Automatically learns schemas and relationships
|
||||
- Supports Belongs-To, One-To-Many and Many-To-Many relationships
|
||||
- Full text search and Aggregations
|
||||
- Rails Auth supported (Redis, Memcache, Cookie)
|
||||
- JWT tokens supported (Auth0, etc)
|
||||
- Highly optimized and fast Postgres SQL queries
|
||||
|
||||
* How does it work?
|
||||
|
||||
GraphQL Input
|
||||
|
||||
query {
|
||||
users{
|
||||
email
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
SQL Output
|
||||
|
||||
SELECT
|
||||
"users_0"."email" AS "email",
|
||||
"users_0"."id" AS "id"
|
||||
FROM (
|
||||
SELECT
|
||||
"users"."email",
|
||||
"users"."id"
|
||||
FROM "users"
|
||||
WHERE ((("users"."id") = ('4'))) limit ('20') :: integer)
|
||||
LIMIT ('20') :: integer))
|
||||
|
||||
* Advanced Queries made simple
|
||||
|
||||
query {
|
||||
products(
|
||||
# Search for all products that contain 'ale' or some version of it
|
||||
search: "ale"
|
||||
|
||||
# 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
|
||||
name
|
||||
search_rank
|
||||
search_headline_description
|
||||
}
|
||||
}
|
||||
|
||||
* Easy to configure
|
||||
|
||||
database:
|
||||
variables:
|
||||
admin_account_id: "5"
|
||||
|
||||
defaults:
|
||||
Filters: ["{ user_id: { eq: $user_id } }"]
|
||||
|
||||
blacklist:
|
||||
- password
|
||||
- secret_token
|
||||
|
||||
fields:
|
||||
- name: users
|
||||
Filters: ["{ id: { eq: $user_id } }"]
|
||||
|
||||
- name: products
|
||||
Filters: [
|
||||
"{ price: { gt: 0 } }",
|
||||
"{ price: { lt: 8 } }"
|
||||
]
|
||||
|
||||
- name: me
|
||||
table: users
|
||||
Filters: ["{ id: { eq: $user_id } }"]
|
95
docs/slides/whygraphql.slide
Normal file
@ -0,0 +1,95 @@
|
||||
Why GraphQL
|
||||
GraphQL is the future of APIs
|
||||
Tags: GraphQL, API, GoLang, Postgres
|
||||
|
||||
Vikram Rangnekar
|
||||
https://twitter.com/dosco
|
||||
|
||||
* Trends, Why APIs are Important
|
||||
|
||||
- An API first world
|
||||
- Rise of API only startups
|
||||
- Rise of integrations
|
||||
- Rise of fullstack developers
|
||||
- Rise of Single-Page-Apps
|
||||
|
||||
* Web Development Today
|
||||
|
||||
A big part of web development is building CRUD APIs to read
|
||||
update and delete things from a database.
|
||||
|
||||
Get all products that belong to user 5
|
||||
.link http://your-startup.com/apis/v1/users/5/products
|
||||
|
||||
Another way to do this
|
||||
.link http://your-startup.com/apis/v1/products?user_id=5
|
||||
|
||||
Maybe you just need only cheaper products
|
||||
.link http://your-startup.com/apis/v1/products?user_id=5&price_under=12
|
||||
|
||||
* So what's the problem here?
|
||||
|
||||
- Too many decisions no real standards
|
||||
- Harder to be consistant
|
||||
- Rinse and repeat for every new API
|
||||
- Too much data over the wire
|
||||
- Boring, we rather work on more interesting things
|
||||
- Slows down dev. cycles
|
||||
|
||||
* GraphQL
|
||||
|
||||
query {
|
||||
user(id: 5) {
|
||||
|
||||
products {
|
||||
id
|
||||
name
|
||||
photo : image
|
||||
|
||||
customers {
|
||||
name
|
||||
email
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
* Perceived bad parts of GraphQL
|
||||
|
||||
- Perceived as new and shiny
|
||||
- Not cache friendly (Not true)
|
||||
- Only best data fetching
|
||||
- New frameworks to learn
|
||||
- Is it just an API gateway?
|
||||
- Write more code
|
||||
|
||||
* Super Graph - An instant GraphQL API for Postgres
|
||||
|
||||
- GraphQL without writing any code
|
||||
- Automatically learns your database
|
||||
- Full text search, Aggregations, etc
|
||||
- Supports Rails cookies and JWT tokens
|
||||
- Join with remote REST APIs
|
||||
- Highly optimized and fast Postgres SQL queries
|
||||
- High performance GO codebase
|
||||
- Tiny docker image and low memory requirements
|
||||
|
||||
* Let's talk about Postgres DB
|
||||
|
||||
- Atomicity, Consistency, Isolation, and Durability
|
||||
- Full support for JSON
|
||||
- Full-text search
|
||||
- Graph DB (WITH RESURSIVE clause)
|
||||
- Timeseries DB (WINDOW functions)
|
||||
- GIS Location DB (PostGIS)
|
||||
- Custom Columns (Bloomfilter, etc)
|
||||
- Nearest Neighbour Searches (GIST Index)
|
||||
- Row level security
|
||||
- Versioning support
|
||||
|
||||
All your micro-services in one
|
||||
|
||||
* Super Graph gives Fullstack Devs superpowers
|
||||
|
||||
|
||||
.iframe https://giphy.com/gifs/3o6ZsYzuLyRfSGX4f6/html5 500 900
|