All Projects → strise → gintonic

strise / gintonic

Licence: MIT license
A declarative transformation language for GraphQL 🍸

Programming Languages

ocaml
1615 projects
javascript
184084 projects - #8 most used programming language
Dockerfile
14818 projects

Projects that are alternatives of or similar to gintonic

Cheatsheets
Quick reference material for techies
Stars: ✭ 66 (+144.44%)
Mutual labels:  code
GitHub-tab-size
📏 Userstyle to set a custom tab-size on GitHub and Gist
Stars: ✭ 17 (-37.04%)
Mutual labels:  code
codeReads
goodReads (pun intended) for coding and programming
Stars: ✭ 29 (+7.41%)
Mutual labels:  code
hastebin-bot
An opensource bot for Discord that posts data to Hastebin
Stars: ✭ 22 (-18.52%)
Mutual labels:  code
Bagel
IPCCC 2018: Robust and Unsupervised KPI Anomaly Detection Based on Conditional Variational Autoencoder
Stars: ✭ 45 (+66.67%)
Mutual labels:  code
playcode
Online Javascript Editor
Stars: ✭ 127 (+370.37%)
Mutual labels:  code
GTAV-Self-driving-car
Self driving car in GTAV with Deep Learning
Stars: ✭ 15 (-44.44%)
Mutual labels:  code
Fundamental-Kotlin
Code examples for the Fundamental Kotlin book.
Stars: ✭ 16 (-40.74%)
Mutual labels:  code
awesome-end2end-speech-recognition
💬 A list of End-to-End speech recognition, including papers, codes and other materials
Stars: ✭ 49 (+81.48%)
Mutual labels:  code
sandboni-core
Sandboni - Java test optimization library which reduces test execution time without compromising quality
Stars: ✭ 27 (+0%)
Mutual labels:  code
PhoneCountryCodePicker
An iOS tableview picker for PhoneCountryCode (English & Chinese supported)
Stars: ✭ 31 (+14.81%)
Mutual labels:  code
i-am-root-nuget-package
📦🏴‍☠️ NuGet package that shows we can run arbitrary code from any NuGet package
Stars: ✭ 22 (-18.52%)
Mutual labels:  code
open source start
Go through the readme... fork ....add....send a pull request .... get yourself in the contribution list...Plant the tree
Stars: ✭ 10 (-62.96%)
Mutual labels:  code
XcodeCommentWrapper
Xcode extension for wrapping comments
Stars: ✭ 29 (+7.41%)
Mutual labels:  code
open-source-DSA-code
open source contribution during hacktoberfest for beginners.
Stars: ✭ 31 (+14.81%)
Mutual labels:  code
Android-Live-Templates
A curated android live templates to make your android development more fast🚀 and easy✨.
Stars: ✭ 197 (+629.63%)
Mutual labels:  code
python-codicefiscale
🇮🇹 💳 encode / decode italian fiscal codes - codifica / decodifica del Codice Fiscale italiano.
Stars: ✭ 53 (+96.3%)
Mutual labels:  code
code-review-culture
📖 The art of cultivating a strong dev culture in your team.
Stars: ✭ 19 (-29.63%)
Mutual labels:  code
Lua-Obfuscator
Obfuscate your lua code because it's so easy to steal!
Stars: ✭ 69 (+155.56%)
Mutual labels:  code
PasteServer
PasteServer to upload text or code
Stars: ✭ 29 (+7.41%)
Mutual labels:  code

Gintonic



A declarative transformation language for GraphQL

This project contains our efforts to build a scalable and maintainable GraphQL transformation tool. This is done by defining a new DSL, which is described and implemented at the gintonic sub-project.

View demo here

Given a transformation, this implementation allows you to do two things:

  1. Apply the transformation to a source schema thus generating a new target schema.
  2. Apply the transformation to a query on the target schema thus generating a new query against the source schema.

Example: Given the schema

type Query {
    field: String
    secretField: String
}

we may apply the transformation

transform type Query {
  # Filter fields and alias 'field' to 'f'
  f: field
}

this transformation filters all fields on type Query that are not field, and aliases that field to f. This will generate the target schema

type Query {
    f: String
}

Now given a query on the target schema:

query {
    f
}

this can be transformed into a valid query on the source schema:

query  {
    f: field
}

Notice that the result of the generated query is valid output for the previous query.

Transformations

The language currently supports five transformation features, which can be applied to the different types and schema when appropriate:

  1. Field and type aliasing: Rename a field or a type
  2. Field filtering: Filter fields from objects or interfaces
  3. Input locking: Supply values to input, thus removing them from the target API
  4. Documenting: Supply or overwrite documentation on fields, arguments, etc.
  5. Schema operation filtering: Filter root-operations.

For each GraphQL type definition (object, union, interface, enum, and input object) and schema definition, there exists a corresponding transformation:

Schema transformation

The schema transformation supports schema operation filtering. This effectively allows you to exclude root operations (query, mutation, or subscription) from your target API.

# Source schema
schema {
    query: Query
    mutation: Mutation
    subscription: Subscription
}

# Transformation
transform schema {
    # Exclude any non-query operations
    query
}

# Target schema
schema {
    query: Query
}

This is a crude but effective way to disallow users from making any mutation calls on your API.

Object type transformation

Object type transformations support field-filtering, field-aliasing, documenting, and input locking on arguments.

# Source type
type Type {
    stringField: String
    fieldWithArguments(arg1: String arg2: String): String
    superSecretField: String
}

# Transformation

"New docs"                                              # Update type docs
transform type T: Type {                                # Type aliasing Type -> T
    stringField                                         # Include string-field
    field: stringField                                  # Field aliasing
    "New docs"                                          # Update field docs
    fieldWithArgument: fieldWithArguments(
        "New docs"
        arg1                                            # Update argument docs
        arg2: "Locked value"                            # Input locking
    )     
    # superSecretField is not specified, so it's filtered.    
}

# Target type

"New docs"
type T {
    stringField: String
    field: String
    "New docs"
    fieldWithArgument(
        "New docs"
        arg1: String
    ): String
}

notice that a field can be transformed an arbitrary number of times. The only limitation is that the target schema must be valid.

Interface type transformation

The interface type transformation supports the same features as the object type transformation.

# Source type
interface Type {
    stringField: String
    fieldWithArguments(arg1: String arg2: String): String
    superSecretField: String
}

# Transformation

"New docs"                                              # Update type docs
transform interface T: Type {                           # Type aliasing Type -> T
    stringField                                         # Include string-field
    field: stringField                                  # Field aliasing
    "New docs"                                          # Update field docs
    fieldWithArgument: fieldWithArguments(
        "New docs"
        arg1                                            # Update argument docs
        arg2: "Locked value"                            # Input locking
    )     
    # superSecretField is not specified, so it's filtered.    
}

# Target type

"New docs"
interface T {
    stringField: String
    field: String
    "New docs"
    fieldWithArgument(
        "New docs"
        arg1: String
    ): String
}

Notice that the validity of a transformation heavily relies upon the validity of the target schema. It is up to the implementer to ensure that all transformations are generating a valid target schema and that all implementing types have the appropriate fields.

Scalar and Union transformations

The scalar and union transformations all support documenting and type-aliasing.

# Source schema
union Union = T1 | T2 | T3

scalar Scalar

# Transformation
"New docs"                      # Type documentation
transform unon U: Union         # Type aliasing

"New docs"                      # Type documentation
transform scalar S: Scalar      # Type alias

# Target schema

"New docs"
union U = T1 | T2 | T3

"New docs"
scalar S

Enum transformation

Similarly to scalar and union transformations, the enum transformation supports documenting and type-aliasing. It does however also support enum value documentation.

# Source schema
enum Enum {
    V1
    V2
}

# Transformation
"New docs"                  # Type docuemntation
transform enum E: Enum {    # Type alias
    "New docs"              # Value documentation
    V1
}

# Target schema
"New docs"
enum E {
    "New docs"
    V1
    V2
}

Input object transformation

The input object transformation supports type-aliasing, documenting, and input locking:

# Source schema

input Input {
    f1: String
    f2: String
}

# Transformation

"new docs"
transform input I: Input {
    "new docs"
    f1
    f2 = "Lock value"
}

# Target schema

"new docs"
input I {
    "new docs"
    f1: String
}

While we could consider doing field aliasing, notice that the input object is fundamentally different from objects. Furthermore, remember that the target schema should always be valid. Therefore locking all fields will yield an input object with no fields in the target schema. This is not valid.

Query transformation

The schema transformations would mean little without the ability to link actually retrieve data from the target API. Therefor graphql-transformer allows you to transform a query against the target API to a query against the source API, where the result can be returned directly to the original caller.

E.g. with the following schemas and transformation:

# Source schema
type Query {
    field(arg: String): String
}

# Transformation
transform type Query {
    f: field(arg = "locked")        # Field aliasing and argument locking
}

# Target schema
type Query {
    f: String
}

an incoming query to the target schema would be transformed into

# Query against the target schema
query {
    f
}

# Transformed query

query {
    f: field(arg: "locked")
}

preserving the output structure, thus making field resolution trivial.

Notice that the target schema should always be served from a GraphQL API resolving meta-fields and validating incoming queries against the target schema.

Koa middleware

You may easily integrate using the provided koa middleware available as a submodule. Read more at gintonic-koa.

Serverless

Gintonic can be deployed on serverless infrastructure using the Koa middleware. An example can be found at examples/serverless.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].