Skip to content

Gateway will merge incorrect data if subgraph changes entity order #271

@smyrick

Description

@smyrick

This is a move over from an issue originally created on the Apollo Federation repo: apollographql/federation#2944

I am recreating over here as this is something that maybe can be caught and logged by this library but the subgraph author still has the responsibility to make sure the entity order does not change, as the apollo-federation-ruby library itself isn't doing something to change the order


Issue Description

An user is building a subgraph with the Ruby library that supports federation. As part of this library, we don't just support a resolve_reference function to resolve a single entity reference but we also have support to resolve multiple with resolve_references (plural): #206

With this new feature, the subgraph now gets the entire entity array and is asked to resolve the specific fields.

[
  {"__typename"=>"Product", "upc"=>"1"},
  {"__typename"=>"Product", "upc"=>"2"},
  {"__typename"=>"Product", "upc"=>"3"}
]

Normally you would only be called once for each entity with resolve_reference and the array order could never change but with this new plural method you could now change the order of the elements. You can still keep the ids the same but you can now return a response to the gateway with the fields filled out but the order changed from what the gateway sent

[
  {"__typename"=>"Product", "upc"=>"3", "inStock": true}, 
  {"__typename"=>"Product", "upc"=>"2",  "inStock": true},
  {"__typename"=>"Product", "upc"=>"1", "inStock": false},
]

If you change that the Gateway responds the Product:1 in stock is true and Product:3 in stock is false which is not correct.

{
  "data": {
    "topProducts": [
      {
        "upc": "1",
        "inStock": true
      },
      {
        "upc": "2",
        "inStock": true
      },
      {
        "upc": "3",
        "inStock": false
      }
    ]
  }
}

This was identified though as not an issue on Gateway as the Federation spec says that the order DOES matter. So in this library maybe we need to add docs to make that more clear or we could even add validation to make sure the order does not change

Link to Reproduction

https://github.com/Gusto/apollo-federation-ruby/compare/main...smyrick:apollo-federation-ruby:shane-gateway-bug?expand=1

Reproduction Steps

  • Start up the example server and gateway here
    • yarn start-services
    • yarn start-gateway
  • Run the following query
    query ExampleQuery {
      topProducts {
        upc
        inStock
      }
    }

See how the data is mismatched

The data is defined like so

INVENTORY = [
  { upc: '1', in_stock: true },
  { upc: '2', in_stock: true },
  { upc: '3', in_stock: false },
]

but the client sees this

{
  "data": {
    "topProducts": [
      {
        "upc": "1",
        "inStock": false
      },
      {
        "upc": "2",
        "inStock": true
      },
      {
        "upc": "3",
        "inStock": true
      }
    ]
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions