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

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

Closed
smyrick opened this issue Feb 23, 2024 · 1 comment
Closed

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

smyrick opened this issue Feb 23, 2024 · 1 comment

Comments

@smyrick
Copy link
Member

smyrick commented Feb 23, 2024

Issue Description

An user is building a subgraph with the Ruby library that supports federation. As part of this library, they don't just support a resolve_reference function to resolve a single entity reference but they also have support to resolve multiple with resolve_references (plural): Gusto/apollo-federation-ruby#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 and the array order could never change but with this 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},
]

In theory the Gateway should be able to do a id match but instead it assume the order is the same so the data returned to clients shows 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
      }
    ]
  }
}

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
      }
    ]
  }
}
@smyrick smyrick changed the title Gateway will merge data for incorrect ids if subgraph changes reference resolve order Gateway will merge data for incorrect ids if subgraph changes entity order Feb 23, 2024
@smyrick smyrick changed the title Gateway will merge data for incorrect ids if subgraph changes entity order Gateway will merge incorrect data if subgraph changes entity order Feb 23, 2024
@smyrick
Copy link
Member Author

smyrick commented Feb 27, 2024

After discussing with the Apollo team, this is actually expected behaviour for Federation, and there fore we are going to close a won't fix.

I will however open up an issue on the Ruby library to maybe see if there is something they can implement on their end since this is a non-standard way of exposing the entities array

https://www.apollographql.com/docs/federation/subgraph-spec/#understanding-query_entities

Screenshot_20240227-120303

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

1 participant