AEB-labs / graphql-weaver

A tool to combine, link and transform GraphQL schemas
MIT License
240 stars 20 forks source link

Linked field returns null when using linkFieldName #28

Open cboileau opened 6 years ago

cboileau commented 6 years ago

Summary

For some reason some virtual fields are returning null for me, while others are working. When I specify the linkFieldName, the endpoint for lc doesn't even get hit to resolve the query. However, if I don't use a linkFieldName, it does hit the lc endpoint, and returns the correct data.

This library is amazing, and I love it, so I'm hoping there is a way to get this to work.

I also have another unrelated question: Is it possible to create more than one link for a field, to support polymorphic relations?

Example of the problem

Schema

const schema = await weaveSchemas({
      endpoints: [{
        namespace: 'cw',
        typePrefix: 'Courseware',
        url: 'http://localhost:2000',
        fieldMetadata: {
          'Assignment.id': {
            link: {
              field: 'rls.rls_resource', // field location in namespace go
              argument: 'external_id', // argument of geo.location,
              linkFieldName: 'resource',
            }
          },
        }
      }, {
        namespace: 'lc',
        typePrefix: 'LearningCurve',
        url: 'http://localhost:2001'
      }, {
        namespace: 'rls',
        typePrefix: 'RLS',
        url: 'http://localhost:2003',
        fieldMetadata: {
          'rlsResource.id': {
            link: {
              field: 'lc.assignment',
              argument: 'assignment_id',
              linkFieldName: 'activity',
              batchMode: false,
            }
          },
        }
      }]
    });

Query

query {
  cw {
    course(id:"15968801-643e-48df-83ca-da275bf4acdd") {
      id
      name
      assignments {
        id
        name
        resource {
          id
          external_id
          activity {
            activity_title
          }
        }
      }
    }
  }
}

Response

{
  "data": {
    "cw": {
      "course": {
        "id": "15968801-643e-48df-83ca-da275bf4acdd",
        "name": "LC Test",
        "assignments": [
          {
            "id": "2d5d1eda-9322-46fa-ad58-9b34558e18fe",
            "name": " Appendix B: Work/Life Satisfaction; I-O Psychology; Motivating Achievement; Leadership",
            "resource": {
              "id": "4340af8d-77bf-40c4-b7a5-83113a576034",
              "external_id": "2d5d1eda-9322-46fa-ad58-9b34558e18fe",
              "activity": null
            }
          },
          {
            "id": "8af965b3-bfbc-4c69-9d93-3fd0b61ea0fe",
            "name": " Appendix B: Career Fields in Psychology",
            "resource": null
          },
          {
            "id": "a783ff43-86c7-4a5e-b863-9c991244cd92",
            "name": " Appendix A: Psychology at Work",
            "resource": null
          },
          {
            "id": "c1f6cdc1-1b71-4113-95ee-aa614a7d075c",
            "name": " Appendix A: Psychology at Work",
            "resource": null
          },
          {
            "id": "5905dd3b-70b8-4b6b-b98f-236656c8f026",
            "name": " 4a. An Introduction to Consciousness and Sleep",
            "resource": {
              "id": "c50f80d4-cfce-47c9-a328-a613e9036aad",
              "external_id": "5905dd3b-70b8-4b6b-b98f-236656c8f026",
              "activity": null
            }
          }
        ]
      }
    }
  }
}

Notice how all of the activity fields are null

Working (without linkFieldName)

Schema

const schema = await weaveSchemas({
      endpoints: [{
        namespace: 'cw',
        typePrefix: 'Courseware',
        url: 'http://localhost:2000',
        fieldMetadata: {
          'Assignment.id': {
            link: {
              field: 'rls.rls_resource', 
              argument: 'external_id', 
              linkFieldName: 'resource',
            }
          },
        }
      }, {
        namespace: 'lc',
        typePrefix: 'LearningCurve',
        url: 'http://localhost:2001'
      }, {
        namespace: 'rls',
        typePrefix: 'RLS',
        url: 'http://localhost:2003',
        fieldMetadata: {
          'rlsResource.id': {
            link: {
              field: 'lc.assignment',
              argument: 'assignment_id',
              batchMode: false,
              // linkFieldName removed
            }
          },
        }
      }]
    });

Query

query {
  cw {
    course(id:"15968801-643e-48df-83ca-da275bf4acdd") {
      id
      name
      assignments {
        id
        name
        resource {
          id {
            activity_title
          }
          external_id
        }
      }
    }
  }
}

Response

{
  "data": {
    "cw": {
      "course": {
        "id": "15968801-643e-48df-83ca-da275bf4acdd",
        "name": "LC Test",
        "assignments": [
          {
            "id": "2d5d1eda-9322-46fa-ad58-9b34558e18fe",
            "name": " Appendix B: Work/Life Satisfaction; I-O Psychology; Motivating Achievement; Leadership",
            "resource": {
              "id": {
                "activity_title": "Appendix B: Work/Life Satisfaction; I-O Psychology; Motivating Achievement; Leadership"
              },
              "external_id": "2d5d1eda-9322-46fa-ad58-9b34558e18fe"
            }
          },
          {
            "id": "8af965b3-bfbc-4c69-9d93-3fd0b61ea0fe",
            "name": " Appendix B: Career Fields in Psychology",
            "resource": null
          },
          {
            "id": "a783ff43-86c7-4a5e-b863-9c991244cd92",
            "name": " Appendix A: Psychology at Work",
            "resource": null
          },
          {
            "id": "c1f6cdc1-1b71-4113-95ee-aa614a7d075c",
            "name": " Appendix A: Psychology at Work",
            "resource": null
          },
          {
            "id": "5905dd3b-70b8-4b6b-b98f-236656c8f026",
            "name": " 4a. An Introduction to Consciousness and Sleep",
            "resource": {
              "id": {
                "activity_title": "4a. An Introduction to Consciousness and Sleep"
              },
              "external_id": "5905dd3b-70b8-4b6b-b98f-236656c8f026"
            }
          }
        ]
      }
    }
  }
}
Yogu commented 6 years ago

Thanks for the bug report! The problem might occur because you are nesting links. I'm thinking of a particular TODO comment... I hope I'll find time to look into this soon.

cboileau commented 6 years ago

Thanks! I was trying to figure out how everything worked in the library so I could make a fix and PR it back, but I think some of it is beyond my understanding. At what point does the single query get split up into multiple requests to the endpoints?

AndersSjo commented 6 years ago

Sitting with the same problem, any ETA on a fix?

Yogu commented 6 years ago

I looked into this a bit more and found out that properly supporting nested links is more tricky than I thought.

It should work by calling weaveSchemas twice, first applying the inner link, then the outer link. Would that work for you?

nyteshade commented 6 years ago

Can you provide a working example?

Yogu commented 6 years ago

Sorry for the delay, I just added a test case demonstrating this workaround.