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

Cannot define JSON Schema Array of Objects #2052

Closed
ddcollins opened this issue Apr 29, 2021 · 4 comments
Closed

Cannot define JSON Schema Array of Objects #2052

ddcollins opened this issue Apr 29, 2021 · 4 comments

Comments

@ddcollins
Copy link

ddcollins commented Apr 29, 2021

Describe the bug
I cannot define type of [Achievement] with JSON schema.

To Reproduce
I've been unsuccessful in being able to define a return of an array of objects.

  - name: AchievementsAPI
    transforms:
      - resolversComposition:
          - resolver: 'Query.*'
            composer: ./src/middleware/reformat-rest-response.js
    handler:
      jsonSchema:
        baseUrl: ${ACHIEVEMENTS_HOST}
        baseSchema: ./src/json-schemas/achievements-api/base-schema.json
        errorMessageField: detail
        disableTimestampScalar: True
        operationHeaders:
          Content-Type: application/json
          Accept: application/json
          X-Api-Token: ${ACHIEVEMENTS_API_TOKEN}
          X-USER-ID: "{context.headers['x-user-id']}"
        operations:
          - type: Query
            field: achievements
            path: /achievements
            method: GET
            responseTypeName: "[Achievement]"

My base schema defines:

{
  "type": "object",
  "properties": {},
  "definitions": {
    "Achievement": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "categoryId": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "createdAt": {
          "type": "string"
        },
        "updatedAt": {
          "type": "string"
        }
      }
    }
  }
}

But I get the error:

TypeError: Cannot read property 'match' of null
    at Interpolator.parseRules (/app/node_modules/@ardatan/string-interpolation/dist/index.js:59:25)
    at Interpolator.parse (/app/node_modules/@ardatan/string-interpolation/dist/index.js:118:24)
    at fieldConfig.resolve (/app/node_modules/@graphql-mesh/json-schema/index.cjs.js:565:72)
    at resolveField (/app/node_modules/graphql/execution/execute.js:464:18)
    at executeFields (/app/node_modules/graphql/execution/execute.js:292:18)
    at executeOperation (/app/node_modules/graphql/execution/execute.js:236:122)
    at executeImpl (/app/node_modules/graphql/execution/execute.js:116:14)
    at Object.execute (/app/node_modules/graphql/execution/execute.js:60:35)
    at /app/node_modules/@graphql-tools/delegate/index.cjs.js:1710:65
    at /app/node_modules/@graphql-tools/delegate/node_modules/@graphql-tools/batch-execute/index.cjs.js:333:37 {
  locations: [],
  path: [ 'graphqlTools0_achievements' ]
}

I've also tried:

{
  "type": "array",
  "items": {
    "$ref": "#/definitions/Achievement"
  }
}

and get the above match error.

I've also tried defining an array of items in a schema file:
./src/json-schemas/achievements-api/achievements.response.json

{
  "$ref": "#/definitions/AchievementsOutput",
  "definitions": {
    "AchievementsOutput": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/Achievement"
      }
    }
  }
}

With mesh file definition of:

  - name: AchievementsAPI
    transforms:
      - resolversComposition:
          - resolver: 'Query.*'
            composer: ./src/middleware/reformat-rest-response.js
    handler:
      jsonSchema:
        baseUrl: ${ACHIEVEMENTS_HOST}
        baseSchema: ./src/json-schemas/achievements-api/base-schema.json
        errorMessageField: detail
        disableTimestampScalar: True
        operationHeaders:
          Content-Type: application/json
          Accept: application/json
          X-Api-Token: ${ACHIEVEMENTS_API_TOKEN}
          X-USER-ID: "{context.headers['x-user-id']}"
        operations:
          - type: Query
            field: achievements
            path: /achievements
            method: GET
            responseSchema: ./src/json-schemas/achievements-api/achievements.response.json

but I get Mesh error:

$ /app/node_modules/.bin/graphql-mesh serve
- Generating Mesh schema...
error: Unable to start GraphQL Mesh: Type with name "AchievementsOutput" does not exists

Expected behavior
A response type of [Achievement] can be defined.

Environment:
node:14.15-alpine

{
  "name": "mesh",
  "dependencies": {
    "@graphql-mesh/cli": "^0.25.1",
    "@graphql-mesh/graphql": "^0.13.17",
    "@graphql-mesh/json-schema": "^0.10.7",
    "@graphql-mesh/transform-encapsulate": "^0.1.27",
    "@graphql-mesh/transform-filter-schema": "^0.9.0",
    "@graphql-mesh/transform-naming-convention": "^0.6.30",
    "@graphql-mesh/transform-rename": "^0.8.1",
    "@graphql-mesh/transform-resolvers-composition": "^0.7.30",
    "dotenv": "^8.2.0",
    "graphql": "^15.4.*",
    "gravatar": "^1.8.1",
    "jsonwebtoken": "^8.5.1",
    "minimist": "^1.2.5",
    "node-fetch": "^2.6.1"
  }
}

I tried updating json schema version and is broken in latest as well.

@ddcollins
Copy link
Author

ddcollins commented Apr 29, 2021

@ardatan Defaulting str to an empty string if null in parseRules resolves the match error.
For some reason str is coming through null here.

Image 2021-04-29 at 2 30 21 PM

@ardatan
Copy link
Owner

ardatan commented May 1, 2021

@ddcollins Did you solve the issue?

@ddcollins
Copy link
Author

ddcollins commented May 1, 2021

@ddcollins Did you solve the issue?

I had an .env header variable that was empty 🤦 . I just coincidentally started trying to use JSON schema at the same time so I attributed it to that (I had working array of objects returning from json samples). What tripped me up even more was the error would only pop when the data response wasn't null so when I'd just set the response to anything other than array of objects the error wouldn't fire. It seems whatever logic was hitting the headers code that would error wouldn't run when the response was null, so it gave me the impression that it was the JSON schema definition, as that was the only "new" thing I was introducing.

@ardatan
Copy link
Owner

ardatan commented May 1, 2021

Maybe we should be able to handle nullish values in string interpolation. Thank you for your explanation :)

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

No branches or pull requests

2 participants