Skip to content

thoughtspot/rise

Repository files navigation

Rise

npm version NodeJS Build Coverage Status

Rise above "REST". A declarative schema driven way to convert REST endpoints to GraphQL. No need to write resolvers and api clients.

Installation

npm i @thoughtspot/rise

Usage

import { rise } from "@thoughtspot/rise";
import { buildSchema } from 'graphql'; // or Apollo or something else.
import typeDefs from './schema.graphql'; // Or your preferred method.


const  { riseDirectiveTransformer, riseDirectiveTypeDefs } = rise({
  // Base URL of the underlying REST Service.
  baseURL: "https://api.service.com/",        
  
  // Forward these headers from the graphql call to REST server.
  forwardheaders: ["cookie", "Authorization"],  
  
  // This is the name of the dynamically created directive.
  name: 'myAwesomeService',                     
  
  // The errors will be thrown from the directive wrapped 
  // in an instance of this class.
  // can be put to "ApolloError" for example to easily use
  // Apollo's error system.
  ErrorClass: ApolloError,
  
  /* 
    Can also specify other directive props here which apply to all REST calls,
    Look at the usage below for all possible props.
  */
});

let schema = buildSchema([
  riseDirectiveTypeDefs,
  typeDefs,
]);

schema = riseDirectiveTransformer(schema);

// .. Serve the schema using your favorite Graphql Server.
# schema.graphql

type Query {
  getUser(id: String!): User!
  @myAwesomeService(
    # path within the REST service  
    path: "/v1/user/$id", 
    
    # API call method GET/POST/PUT/DELETE
    method: "GET",   
    
    # Any additional headers to be sent.
    headers: {
      "accept": "application/json"
    }, 
    
    # content type header value.
    contenttype: "application/json",
    
    # The path to read the the response payload from the response json body.
    resultroot: "data",     
    
    # The path to read the error body from the error response json.
    errorroot: "error",     
    
    # setters are transformations which can be done on the response payload. 
    # For example here 'username' field in gql schema will be
    # mapped to the `header.name` field inside the response json.
    setters:[{
      "field": "username", "path": "header.name"
    }]                      
  )
}

type Mutation {
  createUser(name: String!, groups: [String!], email: String, phone: String, address: String): User!
  @myAwesomeService(
    path: "/v1/user"
    method: "POST",
    contenttype: "application/x-www-form-urlencoded",
    resultroot: "data",
    errorroot: "error",
    
    # postbody can be used to create a custom body for a POST request,
    # this is a lodash template and access to the graphql params is
    # via the `args` keyword.
    # The post body is automatically created from `args` if this option
    # is omitted.
    postbody: """
    {
      "username": "<%= args.name %>",
      "groups": "<%= JSON.stringify(args.groups) %>",
      "properties": {
        "email": "<%= args.email %>",
        "address": "<%= args.address %>",
        "phone": "<%= args.phone %>",
      }
    }
    """   
  )
}

Architecture

ThoughtSpot


Credits

Heavily inspired from StepZen.

About

Rise above "REST" with GraphQL

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •