Faria Rehman July 12, 2019

API Transformer

 

This blog is the fourth part of the series called “API Transformer Recipes”. The series aims to highlight numerous ways in which developers can integrate API Transformer into their workflow in order to gain access to a wide range of tools and frameworks. Hopefully, it will help eliminate any assumptions that they have about being restricted to a particular set of tools just because they use a certain API specification format. 

Announcing support for GraphQL Schema

Oh yes, you heard it right. You can now export GraphQL Schema from APIMatic using  API Transformer! Previously, we provided our users means of migrating from SOAP to REST, and now also aim to facilitate those SOAP/REST users looking to migrate to GraphQL.

Why GraphQL, you wonder? Without going into details, GraphQL is known for being simpler, faster and efficient allowing users to fetch exactly the data they need. Many strongly believe that GraphQL is the future of APIs. So if you are one of them and are considering moving to GraphQL, read on.

Our support for GraphQL schema is currently in beta so we are open to any feedback/suggestions that you might have.

Role of GraphQL Schema

GraphQL schemas for a service are defined using GraphQL SDL (schema definition language) having a pretty simple syntax for defining various components like types, queries, mutations etc. We’ll take a look at some examples later in this blog.

A GraphQL schema is at the core of any GraphQL server implementation. It describes the functionality available to the client applications that connect to it. So having this schema file will serve as a key starting point for migrating your API to GraphQL. You can then easily generate server code, resolver signatures, etc. from it using various tools available out there.

Export GraphQL Schema Files with API Transformer

Bring your API files and export them to GraphQL schema using API Transformer. All major input formats (e.g. OpenAPI, RAML, API Blueprint, etc.) are supported.

The following features of the schema are supported:

  • Object types
  • Scalar and Enumeration types
  • Input types
  • Arguments
  • Queries
  • Mutations
  • Lists and Non-null fields

GraphQL itself does not impose any strict naming conventions other than a list of allowed characters mentioned in their spec. However, keeping in mind some of the best practices highlighted for GraphQL schema designmutations and GraphQL enum types, we follow some conventions to make the migration process for our users easier. These conventions aim to facilitate development and interoperability.

Conventions

  • The names of various components will obey the rules specified in the spec.
  • Object/Input and Enumeration type names will be pascal cased.
  • All field names will be camel cased.
  • Enumeration field names will be upper cased to represent their nature as constants.
  • HTTP verb will be prepended with query/mutation names to represent the action that will be performed upon calling it.

For SOAP Users — Migrating to GraphQL

With  API Transformer, SOAP users can start migrating to GraphQL by obtaining a GraphQL schema file from their service WSDL file. This involves a conversion of all WSDL types to GraphQL schema types, operations to mutations and attributes to arguments. The example below illustrates this:

WSDL example:

<definitions name="HelloService" targetNamespace="http://www.examples.com/wsdl/HelloService.wsdl" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:s="http://www.examples.com/schema1">
  <types>
      <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.examples.com/schema1" elementFormDefault="qualified">
        <element name="GreetingMessage">
            <complexType>
                <sequence>
                    <element name="senderName" type="xsd:string"/>
                    <element name="greeting" type="xsd:string"/>
                </sequence>                
            </complexType>
        </element>
      </schema>
  </types>
  <message name="SendMessageRequest">
      <part name="message" type="s:GreetingMessage"/>
  </message>
  <message name="SendMessageResponse">
      <part name="message" type="s:GreetingMessage"/>
  </message>
  <portType name="Hello_PortType">
      <operation name="sendMessage">
         <input message="tns:SendMessageRequest"/>
         <output message="tns:SendMessageResponse"/>
      </operation>
  </portType>
  <binding name="Hello_Binding" type="tns:Hello_PortType">
      <soap:binding style="rpc"
         transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="sendMessage">
         <soap:operation soapAction="sendMessage"/>
         <input>
            <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:examples:helloservice"
               use="encoded"/>
         </input>    
         <output>
            <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:examples:helloservice"
               use="encoded"/>
         </output>
      </operation>
   </binding>
   <service name="Hello_Service">
      <documentation>WSDL File for HelloService</documentation>
      <port binding="tns:Hello_Binding" name="Hello_Port">
         <soap:address location="http://www.examples.com/SayHello/" />
      </port>
   </service>   
</definitions>

GraphQL schema obtained by converting above WSDL file using  API Transformer:

# API Name: "HelloService"
# Host: http://www.examples.com/SayHello/
# WSDL File for HelloService
type GreetingMessage {
    senderName: String!
    greeting: String!
}
type SendMessageRequest {
    greetingMessage: GreetingMessage!
}
type SendMessageResponse {
    greetingMessage: GreetingMessage!
}
input GreetingMessageInput {
    senderName: String!
    greeting: String!
}
input SendMessageRequestInput {
    greetingMessage: GreetingMessageInput!
}
input CreateSendmessageInput {
    body: SendMessageRequestInput!
}
type Query {
    _: Boolean
}
type Mutation {
    createSendmessage(input: CreateSendmessageInput!): SendMessageResponse!
}
schema {
    mutation: Mutation
    query: Query
}

For REST Users — Layering GraphQL on top

Instead of completely migrating to GraphQL, users generally prefer to add a GraphQL layer on top of REST and enjoy benefits of both. The choice is yours depending on your service and system needs.

You can convert your RESTful API defined in one of the popular formats like OpenAPI/Swagger, RAML, etc. to GraphQL schema with  API Transformer. The conversion process will:

  • Convert GET operations to GraphQL queries while other operations involving server-side changes to GraphQL mutations.
  • Convert complex types in the API to GraphQL object and enumeration types.
  • Wrap operation parameters in a GraphQL input type and link that input type to respective query/mutation arguments.

The example below shows the conversion:

OpenAPI 3.0 example:

openapi: 3.0.0
info:
  title: Calculator
  description: Simple Calculator API
  version: '1.0'
servers:
- url: https://examples.devapi.dream.press/apps/calculator  
paths:
  /{operation}:
    get:
      description: Calculates the expression based on the x and y operator
      operationId: Calculate
      parameters:
      - name: operation
        in: path
        required: true
        schema:
          $ref: '#/components/schemas/OperationType'
      - name: x
        in: query
        required: true
        schema:
          type: number
          format: double
      - name: y
        in: query
        required: true
        schema:
          type: number
          format: double
      responses:
        200:
          description: 'Returns the result of operation'
          content:
            text/plain:
              schema:
                type: number
                format: double      
components:
  schemas:
    OperationType:
      enum:
      - SUM
      - SUBTRACT
      - MULTIPLY
      - DIVIDE
      type: string
      description: Possible operations are sum, subtract, multiply, divide

GraphQL schema obtained by converting above OpenAPI 3.0 file using  API Transformer:

# API Name: "Calculator"
# Host: https://examples.devapi.dream.press/apps/calculator
# Simple Calculator API
"Possible operations are sum, subtract, multiply, divide"
enum OperationType {
    DIVIDE
    MULTIPLY
    SUBTRACT
    SUM
}
input GetCalculateInput {
    operation: OperationType!
    x: Float!
    y: Float!
}
type Query {
    "Calculates the expression based on the x and y operator"
    getCalculate(input: GetCalculateInput!): Float!
}
type Mutation {
    _: Boolean
}
schema {
    mutation: Mutation
    query: Query
}

Conclusion

We hope you found our migration guide to GraphQL useful. If you have any feedback for our GraphQL schema export feature, feel free to reach out.

Continue reading more API Transformer Recipes:

Thanks to Adeel Ali.