Giter Club home page Giter Club logo

openapi-to-graphql's Introduction

Development on OpenAPI-to-GraphQL has paused. GraphQL Mesh is maintaining an OpenAPI/Swagger handler, which is fork of OpenAPI-to-GraphQL. Please find them here.

GitHub last commit Join the chat at https://gitter.im/IBM/openapi-to-graphql

OpenAPI-to-GraphQL

Translate APIs described by OpenAPI Specifications (OAS) or Swagger into GraphQL.

Overview of translation

Getting started

OpenAPI-to-GraphQL can be used in two ways:

CLI

The Command Line Interface (CLI) provides a convenient way to start a GraphQL server wrapping an API for a given OpenAPI Specification:

  1. Install the OpenAPI-to-GraphQL CLI using:
    npm i -g openapi-to-graphql-cli
  2. Then, run the OpenAPI-to-GraphQL command and point it to an OpenAPI Specification:
    openapi-to-graphql <OAS JSON file path or remote url> [options]

For further details, refer to the openapi-to-graphql-cli documentation.

Library

Use OpenAPI-to-GraphQL as a library in your application to generate GraphQL schemas.

  1. Install OpenAPI-to-GraphQL as a dependency:
    npm i -s openapi-to-graphql
  2. Require OpenAPI-to-GraphQL and use the createGraphQLSchema function:
    const { createGraphQLSchema } = require("openapi-to-graphql");
    // load or construct OAS (const oas = ...)
    const { schema, report } = await createGraphQLSchema(oas);

For further details, refer to the openapi-to-graphql documentation.

Tutorials

Here are some guides to further help you get started:

  • CLI + Loopback tutorial: Learn how to quickly spin up GraphQL wrappers using the OpenAPI-to-GraphQL CLI.
  • Library tutorial: Learn how to use OpenAPI-to-GraphQL as a library, and how to improve the resulting GraphQL wrappers using OAS link definitions.
  • LoopBack tutorial: Learn how to use OpenAPI-to-GraphQL to create GraphQL wrappers for APIs created with LoopBack 4.
  • Subscriptions tutorial: Learn how to create a GraphQL API that supports subscription operations - including how to set up the API server that creates a PubSub instance wrapping a MQTT client.

Characteristics

  • Data-centric The GraphQL interface is created around the data definitions in the given OAS, not around the endpoints, leading to a natural use of GraphQL.

    Example of data-centric design
  • Nested data Links defined in the OAS are used to create nested data structures, allowing for (deeply) nested queries.

    Example of links resolution
  • Automatic query resolution Automatically generated resolvers translate (nested) GraphQL queries to API requests. Request results are translated back to GraphQL responses.

    Example of query resolution
  • Mutations Non-safe, non-idempotent API operations (e.g., POST, PUT, DELETE) are translated to GraphQL mutations. Input payload is type-checked.

    Example of mutation
  • Subscriptions GraphQL subscriptions allow clients to receive a stream of events, such as updates whenever data changes on the GraphQL server. OpenAPI-to-GraphQL can create subscriptions based on callback objects defined in the OAS.

    Example of subscription
  • Authentication OpenAPI-to-GraphQL currently supports authentication via API Key and basic auth. OpenAPI-to-GraphQL wraps secured endpoints into a viewer, which takes the API key / credentials as input.

    Example of authentication
  • API Sanitation Parts of an API that not compatible with GraphQL are automatically sanitized. For example, API parameters and data definition names with unsupported characters (e.g., -, ., ,, :, ;...) are removed. GraphQL queries are desanitized to correctly invoke the REST API and the responses are resanitized to create GraphQL-compliant results.

    Example of sanitation
  • Custom request options Provide headers and query parameters to send with every API request. This allows, for example, to handle authentication or tag requests from GraphQL.

  • Swagger and OpenAPI 3 support OpenAPI-to-GraphQL can handle both Swagger (OpenAPI specification 2.0) as well as OpenAPI specification 3.

Development

OpenAPI-to-GraphQL is written in TypeScript. Within each of OpenAPI-to-GraphQL's packages, all source code is contained in the src folder. Use yarn build or yarn test to transpile the source files into the final library in the dist folder. Entry-point for the library is index.js in dist.

Research

Our research paper, "Generating GraphQL-Wrappers for REST(-like) APIs", can be found here. The paper describes the challenges of building OpenAPI-to-GraphQL and an experiment in which we evaluated OpenAPI-to-GraphQL against 959 publicly available OAS, provided by APIs.guru, and successfully created GraphQL interfaces for 89.5% of them.

To run the experiment, in the openapi-to-graphql package, load APIs.guru specifications, found here, into the /tmp folder:

npm run guru-load

Then, run tests:

npm run guru-test <number of APIs to test at most>

Similar projects

  • swagger-to-graphql turns a given Swagger (OpenAPI Specification 2.0) into a GraphQL interface, which resolves against the original API. GraphQL schema is based on endpoints, not on data definitions. No links are considered.

  • json-to-graphql turns given JSON objects / arrays into a GraphQL schema. resolve functions need to be provided by the user.

  • StackOverflow discussion points to the above projects.

License

MIT

openapi-to-graphql's People

Contributors

alan-cha avatar ardatan avatar cancan101 avatar dhmlau avatar dotansimha avatar elsmr avatar eokoneyo avatar erikwittern avatar folding avatar getlarge avatar gtamas avatar imgbotapp avatar laredo avatar marcodaniels avatar marioestradarosa avatar mhassan1 avatar moyara avatar mtth avatar omarchehab98 avatar pagebakers avatar sotaokuhama avatar srchip15 avatar thejibz avatar wtrocki avatar ymglez avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openapi-to-graphql's Issues

Do not publish package-lock.json

As proposed by our StrongLoop colleagues, and as argued for in this issue, publishing the package-lock.json file can shield us from noticing if a dependency breaks OASGraph. We should therefore remove stop publishing it in the future.

Add tests

As we increase the functionality of this library, we should make sure to test our work. I often use tape (https://github.com/substack/tape) for testing (see for example https://github.ibm.com/apiharmony/apih-be/blob/master/test/test_api.js), but have not tried it for GraphQL.

There are some articles on GraphQL testing, using for example Jest (https://medium.com/entria/testing-a-graphql-server-using-jest-4e00d0e4980e) or Mocha/Chai/Sinon (https://medium.com/@FdMstri/testing-a-graphql-server-13512408c2fb). From a first look, I like tape better, but I am open for discussion.

@Alan-Cha1 What do you think?

Create custom resolvers for interpreted object types

As mentioned in #45, we recently made object types default to string. The logic is that, for whatever reason the OAS specifies an unsupported type, we can also interpret that type as a string. We need to create a resolver to handle this case.

Publishing source files onto NPM

Currently, we are publishing the source files, specifically the Typescript files under src/, in our NPM module. Perhaps this is not the best strategy.

Not able to convert swagger openapi spec to GraphQL

Describe the bug
oasgraph cli was not able to convert openapi spec to GraphQL

To Reproduce

oasgraph openapi.json

Expected behavior
GraphQL server is up and running.

Screenshots
screen shot 2018-11-04 at 1 21 13 pm

Please let me know if you need the gist for the openapi.json

Migrate examples and tutorials from IBM Github Enterprise

We have a number of examples and tutorials from IBM Github Enterprise, for example a few on OAuth support, that we would like to make public.

To do so, we would need to make sure the dependencies are updated, the documentation is thoroughly edited, and the code still works.

In the mean time, there are a few links in the current documentation that may lead to IBM Github Enterprise, which users may not have access to.

Generic testing

Most of our tests are built around the example API, which we use for our demos. As a result, it is difficult to balance creating a realistic, well-designed, archetypal API with writing complete test cases.

Right now, I feel that the example API is a hodgepodge of different, unrelated tests. When we need to add new tests, we have to wrangle the API to fit those tests, making both the API and the tests less clear and maintainable.

For example, a single API operation may test not only a specific case of nesting but also a specific response code, CRUD operation, and response body. This is a problem because if something breaks, it may not be immediately obvious what happened. An alternative to overloading an API operation would be to create one-to-one operation-to-test pairings, but this is forced and ugly. For example, while working on issue #18, I have created the GET /cleanDesks and GET /dirtyDesks operations, which was my attempt at fitting the tests to the theme of the example API (which seems to be a corporate database).

While I think it's important that the example API utilizes a fair share of what OASGraph offers, if we continue the trend of using the example API as the main source of our tests, we will be left with huge, monolithic, convoluted mess of an API.

I think we need to make a new API that is used solely for testing. We can name the operations so they closely match the test cases. We also do not need to be pressured into creating operations that fit the API; we can create whatever new operations that fit our need.

Smarter object type name generation

The way that we name new GraphQL Object Types (GOTs) right now is highly varied. All our names are generated from the OAS. Sometimes the name is part of a reference, sometimes it is the name provided by the schema, and sometimes it is a combination of the path and the method. We choose based on the information we have on hand but otherwise, the processes are simple. Because of the different ways we use to generate names, our names lack uniformity. A greater problem is that sometimes, we will end up with long and ugly names.

If we can use smarter methods to create names, hopefully we can create a nicer interface.

Some ideas include: analyzing descriptions for keywords, comparing field names with similar field names in other OASs, and improving the simple parsing that we do already (e.g. getUsers -> users).

JSON schema validation keyword support

JSON schema supports many keywords that can be used to create a more precise JSON schema definition. Some of these keywords are maximum, minimum, allOf, anyOf, and oneOf. We may not be able to support all of these keywords but we would like to begin adding support for some of them.

Support YAML

According to the specification: "An OpenAPI document that conforms to the OpenAPI Specification is itself a JSON object, which may be represented either in JSON or YAML format."

We currently only support JSON. We should make a check for YAML.

Related: issue #66

Pass request-options to OASGraph

In some cases, developers using OASGraph may want to define options to use in the requests made by OASGraph to the REST(-like) API described in a OAS.

For example, the developer may want to pass a custom header x-origin: graphql to each request made by OASGraph, so that the API can monitor the percentage of calls from the GraphQL interface.

Another example is that developers may want to hard-code authentication information (like an OAuth token) to enable requests.

As such, it would be great if these options could be passed on like so:

OasGraph.createGraphQlSchema(oas, {
  headers: { ... },
  queryParameters: { ... }
  ... // maybe something else?
})
.then(...)
.catch(...)

Dealing with dirty OASs

Unfortunately, people are not perfect. Sometimes, we make mistakes. We are only human.

As we continue to test our library against real world OASs, we are constantly surprised by unorthodox specifications. For whatever reason these specifications deviate from the norm, these are the specifications that cause OASGraph to have trouble. This is the eternal question: should we try our best to interpret what the author has set in place or should we only support specifications that strictly follow what has been mandated by OAS?

We would like to support as many APIs as possible, so we are leaning towards the former. However, this means that sometimes, we need to take liberties such as forcing a field to be of type GraphQL String.

Today, we encounter something particularly strange.

"pull_request": {
     "properties": {
          "diff_url": {
               "type": "null"
          },
          "html_url": {
               "type": "null"
          },
          "patch_url": {
               "type": "null"
          }
     },
     "type": "object"
}

Because these properties had a null type, OASGraph could not properly convert the OAS into a GraphQL schema. We fixed this issue by giving fields a default type of string. The logic is that, worst case scenario, if a field was supposed to have an object, array, or number type, that field can always be converted into a string.

We will do our best to document the liberties that we will take to ensure that your OAS can easily be converted into a GraphQL schema with OASGraph.

GraphQL should only be a peer dependency

Currently, GraphQL is listed under both peerDependencies and dependencies.

According to this article, we should have GraphQL listed under only peerDependencies.

However, to remove GraphQL from dependencies would mean we would need to rewrite the documentation to reflect the changes.

Nest GraphQL data-types based on path hierarchy

Some APIs depict hierarchical paths, e.g.:

  • /orgs/{org}
  • /orgs/{org}/events
  • /orgs/{org}/members

(Taken from the OAS of the GitHub API).

Such hierarchical path structures provide an opportunity for nesting corresponding GraphQL types. In the above example, in a query for an organization (via /orgs/{org}), one should also be able to dig into the events or members of that organization. For example:

{
  orgs (org: "facebook") {
    events {
      ...
    }
    members {
      ...
    }
  }
}

To enable such capabilities, the parameter passed to the highest-level resolver needs to be passed on to subsequent resolvers (e.g., using the ctx).

Change our testing system

We currently use the pre-commit NPM module to do our testing. Before every commit, a series of tests will run and if any of the tests fail, then the module will cancel the commit. This restriction can be detrimental to development in certain cases and the testing data is not public.

We would like change to Travis CI. We have tried to do so with pull request #34, however it was unsuccessful because our testing environment is somewhat involved and the changes made did not satisfy the necessary requirements. We need to run multiple processes to run the example API, the graphQL API, and the test queries.

Move library documentation

Currently, the documentation for OASGraph the library is contained in the root README of the repository. The unfortunate side effect is that no proper documentation shows up on the OASGraph npm page:

image

We should move the library documentation to /packages/oasgraph/README.md for this to change, and keep only the bare minimum documentation in the root README.

Separate oasgraph-cli from oasgraph "core"

As discussed in previous comments (#30 (comment) and #30 (comment)) for issue #30, there are good arguments for separating the "core" capabilities of OASGraph (oasgraph) from the ones needed for the CLI (oasgraph-cli), including:

  • Cleaner separation of dependencies, i.e.,. avoiding oasgraph to have to depend on code only needed for the CLI, while still allowing oasgraph-cli to make all dependencies explicit.
  • Improving the getting-started experience by enabling global installation of oasgraph-cli.
  • Reducing the attack-/vulnerability-surface for applications that use oasgraph as a library (in production).

As suggested by @bajtos , we can consider keeping the code in a single repository, though, relying on tools like lerna.

Schema object cannot have additionalProperty LB4 App

Steps to reproduce

  • Create a loopback 4 app
  • Create a datasource to Mysql
  • Create the student model, repository an controller

Make sure it works thru browser. Then follow the oasgraph quick start guide as follows:

  • Clone oasgraph
  • cd to oasgraph
  • run npm link
  • copy the openapi.json file from loopback 4 app running to my current oasgrahp directory (see attached, I placed .txt at the end to allow github attachment)
    using wget http://localhost:3000/openapi.json
  • run oasgraph openapi.json

The following error was received:

{ AssertionError: Schema object cannot have additionalProperty: patternProperties
    at Assertion.fail (/Users/marioestradarosa/test/oasgraph/node_modules/should/as-function.js:275:17)
    at Assertion.value (/Users/marioestradarosa/test/oasgraph/node_modules/should/as-function.js:356:19)
    at checkSubSchema (/Users/marioestradarosa/test/oasgraph/node_modules/oas-validator/index.js:131:16)
    at walkSchema (/Users/marioestradarosa/test/oasgraph/node_modules/oas-validator/node_modules/oas-schema-walker/index.js:53:5)
    at Object.walkSchema (/Users/marioestradarosa/test/oasgraph/node_modules/oas-validator/node_modules/oas-schema-walker/index.js:82:13)
    at checkSchema (/Users/marioestradarosa/test/oasgraph/node_modules/oas-validator/index.js:332:8)
    at checkContent (/Users/marioestradarosa/test/oasgraph/node_modules/oas-validator/index.js:380:13)
    at checkResponse (/Users/marioestradarosa/test/oasgraph/node_modules/oas-validator/index.js:569:9)
    at checkPathItem (/Users/marioestradarosa/test/oasgraph/node_modules/oas-validator/index.js:782:21)
    at Object.validateSync (/Users/marioestradarosa/test/oasgraph/node_modules/oas-validator/index.js:1160:13)
  operator: 'to be above -1',
  message: 'Schema object cannot have additionalProperty: patternProperties',
  actual: -1,
  stackStartFunction: [Function: assert],
  negate: false,
  assertion: 
   Assertion {
     obj: -1,
     anyOne: false,
     negate: false,
     params: 
      { operator: 'to be above -1',
        message: 'Schema object cannot have additionalProperty: patternProperties',
        actual: -1,
        stackStartFunction: [Function: assert],
        negate: false,
        assertion: [Circular] },
     onlyThis: undefined,
     light: false } }

Attached openapi.json file.
openapi.json.txt

Avoid duplicate requests within single query

Currently, queries may resolve to perform duplicate requests. One approach to address this issue is to use dataloaders. However, not every request is deterministic (e.g., the response may contain random values), so the usage of data loaders should be configurable.

Add options to the CLI tool

Currently, the CLI tool just starts up a GraphQL interface. However, with recent developments thanks to people like @marioestradarosa, we are making the CLI tool much more sophisticated. Following this trend, the next step would be to add options to the CLI tool.

Perhaps we will not be able to add all of the options but at least for a few of them, such as the boolean ones, they should be easy to add.

Documentation Request: LB4 vs OASGraph

This is a request for documentation, not a functional issue.

As the README mentions, there are already similar projects. Why use OASGraph? One reason might be that it's the most polished solution, or the 89.5% conversion success rate, but another reason would be that developers trust StrongLoop and are looking specifically for a solution to enhance a LoopBack implementation.

Questions:
1 - Why use OASGraph instead of LoopBack?
2 - How / Why to use OASGraph with LoopBack?
3 - Why the answer to #2 is better than the basic Express + LB + GraphQL solution described on Stack Overflow.
4 - How close is OASGraph to production-ready?

I bring this up mainly because LB4 recently went in GA release and in the announcement, the LB team highlighted OASGraph.

I imagine many developers, like me, are wondering "I'm using LB3 right now and GraphQL seems cool. Should I migrate to LB4 or go straight to OASGraph or some other GraphQL solution?"

Thanks!

nested same property didn't work

Describe the bug
Same labels didn't work

To Reproduce
Input snippet

components:
  schemas:
    RedfishError:
      properties:
        error:
          properties:
            '@Message.ExtendedInfo':
              description: An array of message objects describing one or more error
                message(s).
              items:
                $ref: Message.v1_0_6.yaml#/components/schemas/Message
              type: array
            code:
              description: A string indicating a specific MessageId from the message
                registry.
              type: string
            message:
              description: A human-readable error message corresponding to the message
                in the message registry.
              type: string
          type: object
      type: object
info:
  contact:
    name: DMTF
    url: https://www.dmtf.org/standards/redfish

Error

▶ oasgraph /Users/xxx/Downloads/DSP8010_2018.2/openapi/openapi.yaml --save
/Users/xxx/Downloads/DSP8010_2018.2/openapi/openapi.yaml:6
          properties:
          ^^^^^^^^^^

SyntaxError: Label 'properties' has already been declared
    at new Script (vm.js:51:7)
    at createScript (vm.js:136:10)
    at Object.runInThisContext (vm.js:197:10)
    at Module._compile (internal/modules/cjs/loader.js:618:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)
    at Module.require (internal/modules/cjs/loader.js:598:17)
    at require (internal/modules/cjs/helpers.js:11:18)

Fully adopt GraphQL-js type definitions in source code

We use our fair share of custom data types and as a result, we are at risk of type mismatches. We should try to fully adopt GraphQL data types and their design philosophy (numerous small functions) so that, in case of large changes in the API, we can quickly adapt.

importing doesn't work

import { createGraphQlSchema } from "oasgraph";

When importing in a standalone project it appears that the npm package for 'oasgraph' is not built correctly. Node/Typescript cannot resolve the contents of the oasgraph library.

Question: OASGraph ignores patch?

Looking at the combination loopback 4 and oasgraph, it seems that PATCH is used by lb4 for openapi.json and subsequently ignored by oasgraph. I noticed that PUT is picked up by oasgraph and generates a mutation.

Will lb4 and oasgraph teams be coordinating their approach to openapi application? The direction looks very promising.

Test real-world APIs

OASGraph should be tested against a large set of real-world API specifications. One idea is to write tests against all specifications available in APIs guru.

Error handling

Currently, we OASGraph only considers responses in case everything works out (i.e., a 200 status code). However, errors may occur, and we should come up with a way how these errors can be communicated to the user.

Default descriptions

If the schema does not contain a description, then we default to the summary. If the schema does not contain a summary either, then we default to "No description available." (see line 900 in src/schema_builder.ts).

I think we can do better. At least for the root query fields, we can state the REST call that operation reflects in the description, e.g. "GET api.com/someCall". Maybe we can also clarify the arguments and how they relate to the rest call, which is not always obvious (one example is how non-application/json request bodies get renamed "[sanitized content-type name]Input"). I think we should consider appending this even to pre-existing descriptions as this is important information to know.

Improve CLI and provide tests

The CLI currently depends on custom logic to parse arguments. As we expand the CLI's capabilities, we should consider using a framework like commander.js. This is related to previous issue #44.

We should also refactor the code into a "core" and a "arguments parsing" part to be able to write test cases against the core part.

Product Hunt

I often learn about new frameworks, tools, etc. from Product Hunt. Once this is a bit more polished (Getting Started) -- then I think it would be worthwhile to promote this there.

Link: https://www.producthunt.com/

Getting Started

For http://v4.loopback.io/getting-started-oasgraph.html some things should be changed.

As per a user comment (loopbackio/loopback-next#1762), for git clone it's more preferable to use the https link instead of the ssh link.

That would be a short term thing. As per strongloop/v4.loopback.io#43 the Developer Experience of having to link a dependency is very poor. It's much more preferable to have the following:

npm i -g oasgraph
oasgraph ./openapi.json

and for production a user can install the dependency via package.json and build out a npm script as follows:

start: ./node_modules/oasgraph ./openapi.json

And then be able to run npm start


Lastly the getting started page is very all over the place and not a good guide to "get started" as it currently stands as it assumes a user has an app already.

A much better Getting Started would be to say that lets build on LoopBack's Getting Started ... or add a step to clone a project from LoopBack 4 as follows:

npm i -g @loopback/cli
lb4 example todo
cd example todo // You can even point to LB Documentation for this but it's better if it's all on 1 page. 
npm i oasgraph // After this is available via npm
npm start
// Visit /openapi.json and save to disk at './openapi.json' --> Maybe we can provide a script to pull it from server and save to disk?
Ctrl+C
// Add a command to package.json as follows:
> start:oasgraph: "./node_modules/oasgraph ./openapi.json"
npm run start:oasgraph
// Visit GraphQL Link

.DS_Store file

The .DS_Store file should be added to the .gitignorefile and existing.DS_Storefiles should be removed / deleted (exists indocs` folder). It's a metadata file so not needed in the repo.

Sanitization vs sanitation

We need to be more careful with how we describe "API sanitization/sanitation". There are references to both across the project. I propose we use the term "sanitization/sanitize" because the technical term is "data sanitization".

Link object request body

Regarding link objects, OASGraph currently only considers the parameters field but not request body field.

This may be tricky fix because OASGraph turns request bodies into parameters so we would need to reverse engineer the parameter name from the link object in order to match it. Furthermore, non-application/json request bodies have a wrapper object name so we would also need to check the content type of the linked operation.

createOrReuseDataDef() can create inappropriate object type names for simple schemas

OASGraph reuses object type names based on schemas. This can be a problem if an OAS contains a number of simple schemas, i.e. only have a single property, because these schemas will be associated with the same object type name even though they are used in different contexts.

A good example of a simple schema would be the following:

{
     "type": "string"
}

If this schema was used to describe both a Dog and a Cat object, then they may be both given the same object type name, e.g. both "Dog" or "Cat", by createOrReuseDataDef().


This problem shouldn't be hard to fix. Just write an exception for this edge case. The function getSchemaType() could be helpful.


How I discovered this problem:

Because our test cases mainly deal with complex object types, we did not experience many collisions. Also, this issue will not create errors so it may have just slipped through the cracks.

I encountered when I was trying to enhance non-application/json capabilities. I had to treat the request and response bodies as black boxes. In order to do so, I changed the schemas into the simple schema described above. Because they all had the same schema, they ended up receiving the same object type name. Only when I changed the description did they receive the expected object type names.

Allow use of multiple OAuth tokens for different scopes

Currently, OASGraph can be provided with the location of a single OAuth token in the GraphQL context (542620e). However, based on the concept of scopes in OAuth and OAS, multiple tokens should be supported. To achieve this, the following option could be passed to OASGraph:

{
  tokens: [
    {
      scopes: ['user:profile', 'user:email'],
      path: '$.user.token'
    },
    {
      scopes: ['repo'],
      path: '$.user.repoToken'
    }
  ]
}

Introduce caching options

In some cases, nested GraphQL queries can result in a (large) number of duplicate requests to the wrapped REST-like API. In consequence, many slow HTTP(S) requests need to be performed, backend systems may be burdened, and rate limits may suffer.

One option to avoid this behavior is to introduce caching in the GraphQL layer. Caching would:

  • Be optional and disabled by default
  • Be applicable to query operations only, which we assume to be safe and idempotent

In a first implementation, caching could be enabled globally for all query operations. A maximum cache duration in milliseconds can be provided (with a sensible default). In later implementations, caching could be enabled for selected endpoints only, for example based on the operationId property.

For a simple example of how to enable caching based on the URL of a request, consider: https://github.ibm.com/witternj/secure-graph/commit/23ea7287f2651d220092fced20f88d0bad9d6be7

Access to resolvers?

Is it possible to consume the resolvers directly?
It would be useful to be able to fetch data via the generated interface.

External reference objects

OASGraph can only handle local reference objects as of now. To add external references, we may need to use a REST client.

For example...

Relative link:

$ref: '#/components/schemas/Address'

External link:

$ref: http://example.org/petapi-examples/openapi.json#/components/examples/name-example

Source


If we want to use a REST client to solve this issue, then we may be able to resolve other issues revolving around using a REST client (like express and express-graphql) to support the CLI.

See issue #30 and issue #59


Related: issue #64

Should OASGraph support GraphQL code-generation?

Currently, OASGraph builds up a GraphQL schema including corresponding resolve functions in memory. I think this approach is great for immediately serving the GraphQL interface.

However, having the GraphQL schema in-memory only also has drawbacks:

  • In some settings, the GraphQL schema needs to be re-generated repeatedly. For example, in serverless, it needs to be re-generated for every invocation, which adds around 100 ms for a relatively small OAS.
  • Generated schemas can mostly be used as-is. However, OASGraph may also be considered a starting point for developers to create a GraphQL interface, which they can then extend and maintain.

In consequence, it may be desirable for a library like OASGraph or thereupon-based tools to output source code instead.

One question is whether this would require a dedicated, separate effort, or can be integrated with a library like OASGraph? On the one hand, generating code requires different capabilities from those supported by OASGraph, including templating and writing to file. On the other hand, capabilities present in OASGraph may be re-usable, for example the schema already produced by OASGraph could simply be stringified, or sanitation mappings could be reused.

Handle dirty OAS - or not, if in "strict" mode

OAS are inherently dirty - see https://github.ibm.com/apiharmony/oasgraph/issues/45. E.g., schema definitions can be incomplete or missing completely.

I propose that OASGraph generally attempts to degrade gracefully, i.e., continue to work partially. In some places, this is already the case. For example, when an operation does not have a (valid) return schema defined, OASGraph simply logs a warning. In other cases, OASGraph currently crashes. For example, when the items of an array lack a proper schema definition.

I propose OASGraph per default logs warnings, but continues to work (partially). However, I propose to also introduce a strict option, which, if set to true, will make OASGraph throw an error and exit.

Invalid URI (missing protocol)

I'm using the oasgraph CLI, with a Swagger doc generated from Liberty's built-in API explorer - i.e. I go to /ibm/api/docs and download the JSON it gives me.

When I run a GraphQL request, I get the following response:

{
  "errors": [
    {
      "message": "Invalid URI \"//host:27634/path/to/api\"",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "sysplex"
      ]
    }
  ],
  "data": {
    "sysplex": null
  }
}

It appears that the protocol is not being added to the URI.

With trace on I see:

 http Call GET //host:27634/path/to/api? headers:{"content-type":"application/json","accept":"application/json"} +0ms
  http Error: Invalid URI "//host:27634/path/to/api"
  http     at Request.init (/path/oasgraph/node_modules/request/request.js:273:31)
  http     at new Request (/path/oasgraph/node_modules/request/request.js:127:8)
  http     at request (/path/oasgraph/node_modules/request/index.js:53:10)
  http     at Promise (/path/oasgraph/lib/resolver_builder.js:161:13)
  http     at new Promise (<anonymous>)
  http     at /path/oasgraph/lib/resolver_builder.js:160:16
  http     at resolveFieldValueOrError (/path/oasgraph/node_modules/graphql/execution/execute.js:479:18)
  http     at resolveField (/path/oasgraph/node_modules/graphql/execution/execute.js:446:16)
  http     at executeFields (/path/oasgraph/node_modules/graphql/execution/execute.js:293:18)
  http     at executeOperation (/path/oasgraph/node_modules/graphql/execution/execute.js:237:122) +3ms

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.