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

Extending the schema with additionalResolvers does not work with start command when using namingConvention #4776

Closed
1 of 4 tasks
uzair-inamdar opened this issue Nov 2, 2022 · 8 comments

Comments

@uzair-inamdar
Copy link
Contributor

uzair-inamdar commented Nov 2, 2022

Issue workflow progress

Progress of the issue based on the Contributor Workflow

  • 1. The issue provides a reproduction available on Stackblitz

Make sure to fork this template and run yarn generate in the terminal.

Please make sure Mesh package versions under package.json matches yours.

  • 2. A failing test has been provided
  • 3. A local solution has been provided
  • 4. A pull request is pending review

Describe the bug
In my mesh config file, I am making use of 2 transforms:

  1. namingConvention in wrap mode.
     - namingConvention:
          mode: wrap
          enumValues: upperCase
          typeNames: pascalCase
          fieldNames: camelCase
          fieldArgumentNames: camelCase
    
  2. rename in wrap mode.

I am then extending the schema by providing additional resolvers within the .meshrc.yml file itself.

This works fine with mesh dev but with mesh start I get No field named \"search_accounts\" exists in the type Query from the source Backend error.

To Reproduce on Stackblitz
Steps to reproduce the behavior:

  1. Go to https://stackblitz.com/edit/github-s58jtv?file=.meshrc.yml
  2. Run yarn start:rest in terminal.
  3. Run yarn start:dev in a second terminal section
  4. Make sure you find your way back to the GraphiQL UI. You might have to manually change the 3000 in the url with 4000 (https://github-s58jtv--4000.local-credentialless.webcontainer.io) to get the GraphiQL UI.
  5. In the GraphiQL Ui try the following query:
    query TestQuery {
        getBookById(id: 1) {
            author {
                name
            }
        }
    }
    
    This should work.
  6. Do the same with yarn start in place of yarn start:dev and you should get "No field named \"get_author_by_id\" exists in the type Query from the source Hello World" error.
    Expected behavior
    The resolvers should object stitch the different types together when request is made.

Environment:

  • OS: MacOS Monterey
  • @graphql-mesh/cli: 0.78.39
  • @graphql-mesh/openapi: 0.33.28
  • @graphql-mesh/transform-naming-convention: 0.11.13
  • @graphql-mesh/transform-rename: 0.12.95
  • NodeJS: 16.14.0

Additional context

I tried to debug through @graphql-mesh/utils/index.js and saw that the field names in the context object are in camelCase while the schema object still has them in snake_case. I'm assuming that's is somehow what's causing the error.

@uzair-inamdar
Copy link
Contributor Author

I really tried to create a stackblitz, but it's really hard to replicate my development environment.

@ardatan
Copy link
Owner

ardatan commented Nov 2, 2022

I really tried to create a stackblitz, but it's really hard to replicate my development environment.

We need it in order to help you :)

@uzair-inamdar
Copy link
Contributor Author

I really tried to create a stackblitz, but it's really hard to replicate my development environment.

We need it in order to help you :)

Updated the description with a stackblitz. Running it is a little complicated, but it should show the error.

@uzair-inamdar
Copy link
Contributor Author

@ardatan any update on this? This is preventing us from using mesh start on our production servers.

@uzair-inamdar uzair-inamdar changed the title Extending the schema with additionalResolvers does not work with start command Extending the schema with additionalResolvers does not work with start command when using namingConvention Nov 7, 2022
@ardatan
Copy link
Owner

ardatan commented Nov 7, 2022

No update so far. PRs are welcome from anyone interested in.

@theguild-bot theguild-bot mentioned this issue Nov 10, 2022
@rushairer
Copy link

Maybe I have the same question.

.meshrc.yaml

...
                  - type: Query
                    field: pMediaList
                    path: /platformmedia/list
                    method: GET
                    responseSchema: ./json-schemas/applist-schemas.json#/definitions/PMediaDetailResults
....
transforms:
    - namingConvention:
          typeNames: pascalCase
          enumValues: upperCase
          fieldNames: camelCase
          fieldArgumentNames: camelCase
additionalTypeDefs: |
    type AppInfo {
        pMediaList: PMediaDetailResults
    }
    extend type Query {
       getAppInfo: AppInfo
    }
additionalResolvers:
    - ./additionalResolvers

applist-schemas.json

"PMediaDetail": {
            "type": "object",
            "title": "PMediaDetail",
            "description": "PMediaDetail Object",
            "properties": {
                "id": {
                    "type": "integer"
                },
                "media_name": {
                    "type": "string"
                }
            }
        },
        "PMediaDetailResults": {
            "type": "object",
            "title": "PMediaDetailResults",
            "description": "PMediaDetail Results",
            "properties": {
                "code": {
                    "type": "integer"
                },
                "data": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/PMediaDetail"
                    },
                    "uniqueItems": true
                }
            }
        }

additionalResolvers.ts

/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { Resolvers } from './.mesh'
export const resolvers: Resolvers = {
    Query: {
        getAppInfo: async (root, args, context, info) => {
            const pMediaList =
                await context.SspIdCoreRESTFulApi.Query.pMediaList({
                    root,
                    args,
                    context,
                    info,
                    selectionSet: /* GraphQL */ `
                        {
                            code
                            data {
                                id
                                mediaName
                            }
                        }
                    `,
                    valuesFromResults: (results) => {
                        // console.log(results.data[0].mediaName)
                        return {
                            code: results.code,
                            data: [
                                {
                                    id: results.data[0].id,
                                    mediaName: results.data[0].mediaName,   // not work, it will get mediaName: null
                                    media_name: results.data[0].mediaName, // well, get mediaName: "xxxxxxxxxxxxx" 
                                },
                            ],
                        }
                    },
                })

            return {
                pMediaList,
            }
        },
    },
}

When I using snakeCase in API side, setting fieldNames: camelCase is OK.

Now I want add a type named AppInfo to multi-select pMediaList and anthor data.
In Resolvers code of valuesFromResults, mediaName will not work, but media_name is OK.
Is a valuesFromResults function necessary?

@rushairer
Copy link

Maybe I have the same question.

.meshrc.yaml

...
                  - type: Query
                    field: pMediaList
                    path: /platformmedia/list
                    method: GET
                    responseSchema: ./json-schemas/applist-schemas.json#/definitions/PMediaDetailResults
....
transforms:
    - namingConvention:
          typeNames: pascalCase
          enumValues: upperCase
          fieldNames: camelCase
          fieldArgumentNames: camelCase
additionalTypeDefs: |
    type AppInfo {
        pMediaList: PMediaDetailResults
    }
    extend type Query {
       getAppInfo: AppInfo
    }
additionalResolvers:
    - ./additionalResolvers

applist-schemas.json

"PMediaDetail": {
            "type": "object",
            "title": "PMediaDetail",
            "description": "PMediaDetail Object",
            "properties": {
                "id": {
                    "type": "integer"
                },
                "media_name": {
                    "type": "string"
                }
            }
        },
        "PMediaDetailResults": {
            "type": "object",
            "title": "PMediaDetailResults",
            "description": "PMediaDetail Results",
            "properties": {
                "code": {
                    "type": "integer"
                },
                "data": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/PMediaDetail"
                    },
                    "uniqueItems": true
                }
            }
        }

additionalResolvers.ts

/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { Resolvers } from './.mesh'
export const resolvers: Resolvers = {
    Query: {
        getAppInfo: async (root, args, context, info) => {
            const pMediaList =
                await context.SspIdCoreRESTFulApi.Query.pMediaList({
                    root,
                    args,
                    context,
                    info,
                    selectionSet: /* GraphQL */ `
                        {
                            code
                            data {
                                id
                                mediaName
                            }
                        }
                    `,
                    valuesFromResults: (results) => {
                        // console.log(results.data[0].mediaName)
                        return {
                            code: results.code,
                            data: [
                                {
                                    id: results.data[0].id,
                                    mediaName: results.data[0].mediaName,   // not work, it will get mediaName: null
                                    media_name: results.data[0].mediaName, // well, get mediaName: "xxxxxxxxxxxxx" 
                                },
                            ],
                        }
                    },
                })

            return {
                pMediaList,
            }
        },
    },
}

When I using snakeCase in API side, setting fieldNames: camelCase is OK.

Now I want add a type named AppInfo to multi-select pMediaList and anthor data. In Resolvers code of valuesFromResults, mediaName will not work, but media_name is OK. Is a valuesFromResults function necessary?

I fix it now.

https://www.the-guild.dev/graphql/mesh/docs/transforms/transforms-introduction#two-different-modes

Add transforms at the source level will fix it.

@uzair-inamdar
Copy link
Contributor Author

#4776 (comment) fixed it for me.

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

3 participants