Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend OAS implementations #440

Merged
merged 4 commits into from
Jan 28, 2022
Merged

Extend OAS implementations #440

merged 4 commits into from
Jan 28, 2022

Conversation

eokoneyo
Copy link
Contributor

@eokoneyo eokoneyo commented Jan 23, 2022

Hi, following our discussion in #426 , I decided to open a different PR to tackle couple of issues I found pertaining to how the definitions from an OAS might be processed.

Here's a couple of issues the PR addresses;

  • Fixes implementation where the style and explode properties for endpoint parameters didn't adhere to the Open API Spec. Given the partial definition;

    "/api/path": {
      get: {
       "parameters" : [ {
              "name" : "parameters",
              "in" : "query",
              "required" : true,
              "style" : "form",
              "explode" : true,
              "schema" : {
                "$ref" : "#/components/schemas/SomeSchemaInput"
              }
        } ],
      }
    }
    

    where SomeSchemaInput has properties of filter and limit for example, I found that the http request made for the generated GraphQL resolver is of the format; http://{baseUrl}/api/path?parameters[limit]=10&parameters[offset]=10 when the http request url should rather be http://{baseUrl}/api/path?limit=10&offset=10 considering the provided values for style and explode, as defined in Open API specification. Relates to Adds query string serialization optimization #312 but also includes support for Arrays and Objects

  • Also fix issue where an error is thrown when link is created with parameter that's a nested object; for instance given the link definition;

    ...
            responses: {
              200: {
                links: {
                  invitations: {
                    operationId: 'someOperationId',
                    parameters: {
                      filter: {
                        entityId: '$response.body#/id',
                      },
                    },
                  },
                },
              },
    
    

    previously filter would be attempted to be processed as a string, which resulted in errors.

@eokoneyo eokoneyo marked this pull request as ready for review January 23, 2022 17:48
@Alan-Cha
Copy link
Collaborator

@eokoneyo Thank you so much for the follow up! I will take a closer look at this later today and try to get it in. This is looking great so far!

@Alan-Cha
Copy link
Collaborator

Alan-Cha commented Jan 28, 2022

Okay, I have reviewed this and I generally like what I see! I have a few comments, however, which I will try to address. All in all, I think we can merge this in!

source,
args
}: inferLinkArgumentsParam<TSource, TContext, TArgs>) {
if (Object.prototype.toString.call(value) === '[object Object]') {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like this pattern. It seems a bit lengthy and we don't use this pattern anywhere else in our code base. I believe that typeof value === 'object' should be sufficient for this use case. Feel free to correct me if I am wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using the prototype method might be overkill, but it does guarantee we are dealing with a real object but I think typeof should suffice in this case.

Signed-off-by: Alan Cha <[email protected]>
await graphql(createdSchema, query).then((result) => {
// target error field because the corresponding server url is not implemented,
// also we get the full request url as in failed request errors
result.errors.forEach((error) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for adding a test case! Adding test cases make my life so much easier.

This is certainly an interesting way to test this functionality, to create an error and examine the request. I think it would be really interesting if we could extract the backend requests that we are making and use them for test cases but I think this pattern isn't the best way to do this.

I am currently working on another issue that I have come across which will also require me to rework this test. We can accept this for now.

*/
function inferLinkArguments (paramName, value, resolveData, source, args) {
if (Object.prototype.toString.call(value) === '[object Object]') {
return Object.entries(value).reduce((acc, [key, value]) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this issue as well! However, I think we are missing a test for this and while I was trying to add it in, I came across some other issues...

}, {})
}

if (value.search(/{|}/) === -1) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... namely, we cannot assume that value is a string. There seems to be a mismatch with our type definitions and OAS.

@@ -55,7 +55,7 @@ type AuthOptions = {

type GetResolverParams<TSource, TContext, TArgs> = {
operation: Operation
argsFromLink?: { [key: string]: string }
argsFromLink?: { [key: string]: any }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right... I totally missed this, thanks for spotting this

}, {})
}

if (typeof value !== 'string') {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As well as a check here. However, I am still working on finishing a test but unfortunately I don't think I will be able to finish this today and I really want to get this checked in. I think for our purposes, this PR is good enough to get merged in!

@Alan-Cha Alan-Cha merged commit fbefbac into IBM:master Jan 28, 2022
@Alan-Cha
Copy link
Collaborator

@eokoneyo It's in! Thanks so much again! I know this fix and the old PR has been getting really stale. This was a really great change! Thank you once again!

@eokoneyo eokoneyo deleted the feature/extend-OAS-implementations branch March 14, 2022 15:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants