Skip to main content
Join the official 2019 Python Developers SurveyStart the survey!

The web framework

Project description

GraphQL Facade

GraphQL Facade is a python application-intermediary between a frontend application using GraphQL and a REST application on the backend oriented declarative style of the description of the services.

GraphQL Facade allow

  • make a requests to the REST service using GraphQL language
  • use batch loading (subject to the rules)

Adding new REST service to the Application

To add a new service, you need to perform several steps:

  1. create a description of the data schema in graphql syntax
  2. create REST service description (yaml or json supported)
  3. describe resolvers (yaml or json)
  4. add schema description to main configuration file
  5. specify the Base Url of the service in the application settings

REST service description

<service_name>: 
    <endpoint_name>:
        method: <METHOD>
        path: <PATH>

service_name: Name of your REST API service.
endpoint_name: Name of your REST endpoint.
method: GET, POST, PATCH, PUT, DELETE (GET default)
path: path to yor endpoint

Resolvers

<Parent_name.field_name>:
    endpoint: <service_name.endpoint_name>
    batch: True
    args:
        <param_name>: <param_value>
    loader: <path.to.your.custom.resolver_file.resolver_name>

Parent_name.field_name: field name in your graphql schema (Query.name for example)
endpoint: your rest endpoint for this data field in service_name.endpoint_name format
loader: path to custom resolver (not a required field). Use python site-packages syntax
args: if you want to use any params to make request to REST you can set args field. param_name - an arbitrary name of the variable, param_value - arbitrary value. To use the attributes of a parent element, use parent. the prefix and then the name of the attribute. for examle post_is: parent.id batch: use batch loading. False by default

Schemas description

schemas:
  <schema_name>:
    url: <schema_url>
    resolvers: <path/to/your/resolvers/file>
    sdl:
      - <list/of/paths/to/sdl/directories>
      - <or/and/sdl/files>

rest:
  - <list/of/paths/to/your/rest/description/files>

schema_name: your schema name
url: url to graphql endpoint (by default equal to schema name)
resolvers: path (relative to base directory) to your resolvers file
sdl: list of paths to .graphql files (schema descriptions) or directories with .graphql files
rest: list of paths to rest definition files (relative to base directory)

REST App connection Example

Let's say you have a REST service with signature: Input:

{
    id: [0, 1, 2],
    q: "any search string"
}

Output:

{
  "pagination": {
    "total": 0,
    "offset": 0,
    "limit": 0
  },
  "result": [
    {
      "conditions": {},
      "calculator_id": 0,
      "version": 0,
      "created": "2019-08-29T09:09:23.048Z",
      "terms": [
        0
      ],
      "status": "archive",
      "updated": "2019-08-29T09:09:23.048Z",
      "amounts": [
        0
      ],
      "priority": 0,
      "title": "string",
      "meta": {},
      "id": 0
    }
  ]
}

for connect your api to GraphQL facade follow that steps:

preview

As a result of all the steps we get the structure (files and directories that we will not use are omitted)

-app
    -graphql
        -calculator
            -sdl
                mutation.graphql
                query.graphql
            loaders.py
            resolvers.yaml
            rest.yaml
        ...
    init_facade.yaml
    ...
...

.graphql files - description of your data schema
loaders.py custom resolvers (if you need)
resolvers.yaml description of resolvers
rest.yaml description of rest api service
init_facade.yaml description all schemas and file paths for schema

the file scheme is conditional and not mandatory but it is recommended to adhere to this rule of file location and naming

1. describe data schema

the data schema describes data types and arguments for our REST service it will have the following form

app/graphql/calculator/sdl/query.graphql
type Query {
    calculators(id: [Int], q: String): Calculators
    }

type Calculators{
    pagination: Pagination
    result: [Calculator]
    }

type Calculator {
    id: Int
    created: String
    updated: String
    calculator_id: Int
    status: String
    version: Int
    title: String
    amounts: [String]
    terms: [Int]
    meta: String
    priority: Int
    conditions: String
    }

type Pagination {
    total: Int
    limit: Int
    offset: Int
    }

2. REST service description

REST description files contains information about paths to your REST handlers

for our API:

app/graphql/calculator/rest.json
{
  "calculator": {
    "find_calculators": {
      "method": "GET",
      "path": "/api/v1/pdl_calculators/"
    }
}

3. describe resolvers

Resolvers files explain how to receive Schema fields (which REST handler to use, whether to use bath loading or smth else)

app/graphql/calculator/resolvers.json
{
  "Query.calculators": {
    "endpoint": "calculator.find_calculators"
  }
}

4. main configuration file

app/init_facade.yaml

Configuration file describe file location for our schema

schemas:

  calculator:
    url: calculator
    resolvers: app/graphql/calculator/resolvers
    sdl:
      - app/graphql/calculator/sdl

rest:
  - app/graphql/calculator/rest

5. base url to config

It is important not to forget to specify URLs in the application settings We do not specify base_url in yaml or json files to be able to pass base_url as environment variables

Key must match to REST service name in rest.yaml file

settings/config.py
class Config:
...
    BASE_URLS = {
                 ...
                 'calculator': env.str('calculator_api', default='http:/calculator.prod.com')
                 ...
                }
...

Batch loading

For use batch loading you must follow few simple rules:

  • REST API endpoint must accept a list of id arguments
  • REST must return list of records (which perform a conditions of a request) in result field and send id field to each row
    for example:
{
  "pagination": {
    "total": 2,
    "limit": 10,
    "offset": 0
  },
  "result": [
    {
      "id": 1
    },
    {
      "id": 2
    }
  ],
  "success": true
}
  • finally set batch = True in your fields resolver description:
Calculator.calculator:
    endpoint: /api/v1/calculator
    batch: True

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for gql-ext, version 0.0.13
Filename, size File type Python version Upload date Hashes
Filename, size gql_ext-0.0.13-py3-none-any.whl (20.3 kB) File type Wheel Python version py3 Upload date Hashes View hashes
Filename, size gql_ext-0.0.13.tar.gz (18.7 kB) File type Source Python version None Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page