A representation is a map that can be transferred from one implementing service to another, within the same federation. This is necessary to allow work started in one service to continue in another; consider the query:

    userById(id: "124c41") { 
        favoriteProducts { upc name price } 

The gateway will query the User/favoriteProducts field on the products service as the second step on this query … but where does the User come from?

After the gateway performs the initial query on the users service, it builds a representation of the specific User to pass to the products service, using information from the @key directive:

{"__typename": "User",
 "id": "124c41"}

This representation is JSON, and is passed to an implementing service’s _entities query, which is automaticaly added to the implementing service’s schema by Lacinia:

scalar _Any
scalar _FieldSet

# a union of all types that use the @key directive
union _Entity

extend type Query {
  _entities(representations: [_Any!]!): [_Entity]!

The _Entity union will contain all entities, internal or external, in the local schema; for the products service, this will be User (external) and Product (internal).

The _entities query exists to convert some number of representations (here, as scalar type _Any) into entities (either stub entities or full entities). The gateway sends a request that passes the representations in, and uses fragments to extract the data needed by the original client query:

query($representations:[_Any!]!) {
    _entities(representations:$representations) {
        ... on User {
            favoriteProducts {upc name price}

So, in the products service, the _entities resolver converts the representation into a stub User object, containing just enough information so that the favoriteProducts resolver can perform whatever database query it uses. The response from the products service is merged together with the response from the users service and a final response can be returned to the gateway service’s client.