Apollo router and hive federation

Hi guys, I am self hosting hive with composite server, and using a MS architecture coupled with several MS that push their schema to hive.

Apollo router then queries hive for the schema and router the traffic. All is working very well, except federation. I’m using federation V1, as hive does not seem to be compatible with V2 yet ( I was getting KeySet! value is not _KeySet! or something).

My question is I am getting this error when trying to set up federation:

{
  "data": {
    "property": null
  },
  "errors": [
    {
      "message": "service 'apartment' response was malformed: invalid value: integer `-1`, expected u32",
      "extensions": {
        "service": "apartment",
        "reason": "invalid value: integer `-1`, expected u32",
        "code": "SUBREQUEST_MALFORMED_RESPONSE"
      }
    }
  ],
  "extensions": {
    "valueCompletion": [
      {
        "message": "Cannot return null for non-nullable field Property.apartments",
        "path": [
          "property"
        ]
      }
    ]
  }
}

The query get’s to the property MS, but never I see any logs in the apartment MS that would indicate that the query get’s that far.

Here are the 2 subgraphs registered in hive for Apartments/Properties:

"Marks the field, argument, input field or enum value as deprecated"
directive @deprecated(
  "The reason for the deprecation"
  reason: String = "No longer supported"
) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION

"Marks target object as extending part of the federated schema"
directive @extends on OBJECT | INTERFACE

"Marks target field as external meaning it will be resolved by federated schema"
directive @external on FIELD_DEFINITION

"Directs the executor to include this field or fragment only when the `if` argument is true"
directive @include(
  "Included when true."
  if: Boolean!
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

"Space separated list of primary keys needed to access federated object"
directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE

"Specifies the base type field set that will be selectable by the gateway"
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION

"Specifies required input field set from the base type for a resolver"
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION

"Directs the executor to skip this field or fragment when the `if` argument is true."
directive @skip(
  "Skipped when true."
  if: Boolean!
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

"Exposes a URL that specifies the behaviour of this scalar."
directive @specifiedBy(
  "The URL that specifies the behaviour of this scalar."
  url: String!
) on SCALAR

union _Entity = Property

type GraphqlPropertyDeleteOutput {
  deleted: Boolean!
}

type Mutation {
  "Create property mutation"
  createProperty(input: GraphqlCreatePropertyInput!): Property
  "Delete property mutation"
  deleteProperty(input: GraphqlDeletePropertyInput!): GraphqlPropertyDeleteOutput
  "Update property mutation"
  updateProperty(input: GraphqlUpdatePropertyInput!): Property
}

type Property @key(fields: "primaryKey") {
  capacity: Int!
  city: String!
  country: String!
  createdAt: String!
  currency: Currency!
  description: String!
  landlordName: String!
  name: String!
  numberOfFloors: Int!
  numberOfRooms: Int!
  ownerUUID: String!
  postCode: String!
  primaryKey: String!
  propertyType: PropertyType!
  sizeOfPropertyInSqM2: Int!
  state: String!
  street: String!
  streetNr: Int!
  updatedAt: String!
}

type Query @extends {
  "Union of all types that use the @key directive, including both types native to the schema and extended types"
  _entities(representations: [_Any!]!): [_Entity]!
  _service: _Service!
  "Filter properties query"
  filterProperties(input: GraphqlFilterPropertiesInput!): [Property!]!
  "Get property query"
  getProperty(input: GraphqlGetPropertyInput!): Property
  property(primaryKey: String!): Property
}

type _Service {
  sdl: String!
}

enum Currency {
  EURO
  GBP
  USD
}

enum PropertyType {
  CO_LIVING_SPACES
  SERVICED_APARTMENTS
  STUDENT_ACCOMMODATION
}

"Federation scalar type used to represent any external entities passed to _entities query."
scalar _Any

"Federation type representing set of fields"
scalar _FieldSet

input GraphqlCreatePropertyInput {
  capacity: Int!
  city: String!
  country: String!
  currency: Currency!
  description: String!
  landlordName: String!
  name: String!
  numberOfFloors: Int!
  numberOfRooms: Int!
  ownerUUID: String!
  postCode: String!
  propertyType: PropertyType!
  sizeOfPropertyInSqM2: Int!
  state: String!
  street: String!
  streetNr: Int!
}

input GraphqlDeletePropertyInput {
  primaryKey: String!
}

input GraphqlFilterPropertiesInput {
  capacity: Int
  city: String
  country: String
  name: String
  ownerUUID: String
  postCode: String
  propertyType: PropertyType
  state: String
}

input GraphqlGetPropertyInput {
  primaryKey: String!
}

input GraphqlUpdatePropertyInput {
  capacity: Int
  city: String
  country: String
  currency: Currency
  description: String
  landlordName: String
  name: String
  numberOfFloors: Int
  numberOfRooms: Int
  ownerUUID: ID
  postCode: String
  primaryKey: String!
  propertyType: PropertyType
  sizeOfPropertyInSqM2: Int
  state: String
  street: String
  streetNr: Int
}
"Marks the field, argument, input field or enum value as deprecated"
directive @deprecated(
  "The reason for the deprecation"
  reason: String = "No longer supported"
) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION

"Marks target object as extending part of the federated schema"
directive @extends on OBJECT | INTERFACE

"Marks target field as external meaning it will be resolved by federated schema"
directive @external on FIELD_DEFINITION

"Directs the executor to include this field or fragment only when the `if` argument is true"
directive @include(
  "Included when true."
  if: Boolean!
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

"Space separated list of primary keys needed to access federated object"
directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE

"Specifies the base type field set that will be selectable by the gateway"
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION

"Specifies required input field set from the base type for a resolver"
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION

"Directs the executor to skip this field or fragment when the `if` argument is true."
directive @skip(
  "Skipped when true."
  if: Boolean!
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

"Exposes a URL that specifies the behaviour of this scalar."
directive @specifiedBy(
  "The URL that specifies the behaviour of this scalar."
  url: String!
) on SCALAR

union _Entity = Property

type Apartment {
  apartmentType: ApartmentType!
  capacity: Int!
  cost: String!
  createdAt: String!
  description: String!
  ensuite: Boolean!
  name: String!
  numberOfRooms: Int!
  optionalAmenities: [String!]!
  ownerUUID: String!
  primaryKey: String!
  secondaryKey: String!
  sharedKitchen: Boolean!
  sizeInSqm2: Int!
  standardAmenities: [StandardAmenities!]!
  updatedAt: String!
}

type GraphqlApartmentDeleteOutput {
  deleted: Boolean!
}

type Mutation {
  "Create apartment mutation"
  createApartment(input: GraphqlCreateApartmentInput!): Apartment
  "Delete apartment mutation"
  deleteApartment(input: GraphqlDeleteApartmentInput!): GraphqlApartmentDeleteOutput
  "Update apartment mutation"
  updateApartment(input: GraphqlUpdateApartmentInput!): Apartment
}

type Property @extends @key(fields: "primaryKey") {
  apartments: [Apartment!]!
  primaryKey: String! @external
}

type Query @extends {
  "Union of all types that use the @key directive, including both types native to the schema and extended types"
  _entities(representations: [_Any!]!): [_Entity]!
  _service: _Service!
  apartment(primaryKey: String!): [Apartment!]
  "Get all apartments for property query"
  getAllApartmentsForProperty(input: GraphqlGetAllApartmentsInput!): [Apartment!]!
  "Get apartment query"
  getApartment(input: GraphqlGetApartmentInput!): Apartment
}

type _Service {
  sdl: String!
}

enum ApartmentType {
  CONDO
  DUPLEX
  GARDEN_APARTMENT
  LOFT
  PENTHOUSE
  SERVICED_APARTMENT
  SHARED_APARTMENT
  STUDIO
}

enum StandardAmenities {
  BEDDING
  BICYCLE_STORAGE
  CUBY_SUPPORT
  FURNISHED
  GYM
  INDOOR_PARKING_SPACE
  INDOOR_POOL
  IN_HOUSE_SUPERMARKET
  LETTER_BOX
  OUTDOOR_PARKING_SPACE
  OUTDOOR_POOL
  POST_BOX
  PUBLIC_PARKING
  ROOFTOP_TERRACE
  SAUNA
  SHARED_LOBBY
  SHARED_LOUNGE
  STORAGE
  TOWELS
  TV
  UTILITIES_EXPENSES
  WI_FI
  YOGA_STUDIO
}

"Federation scalar type used to represent any external entities passed to _entities query."
scalar _Any

"Federation type representing set of fields"
scalar _FieldSet

input GraphqlCreateApartmentInput {
  apartmentType: ApartmentType!
  capacity: Int!
  cost: String!
  description: String!
  ensuite: Boolean!
  name: String!
  numOfRooms: Int!
  optionalAmenities: [String!]!
  ownerUUID: String!
  primaryKey: String!
  sharedKitchen: Boolean!
  sizeInSqm2: Int!
  standardAmenities: [StandardAmenities!]!
}

input GraphqlDeleteApartmentInput {
  primaryKey: String!
  secondaryKey: String!
}

input GraphqlGetAllApartmentsInput {
  primaryKey: String!
}

input GraphqlGetApartmentInput {
  primaryKey: String!
  secondaryKey: String!
}

input GraphqlUpdateApartmentInput {
  apartmentType: ApartmentType
  capacity: Int
  cost: String
  description: String
  ensuite: Boolean
  name: String
  numOfRooms: Int
  optionalAmenities: [String!]
  ownerUUID: String
  primaryKey: String!
  secondaryKey: String!
  sharedKitchen: Boolean
  sizeInSqm2: Int
  standardAmenities: [StandardAmenities!]
}

I run Apollo router with this command

docker run --net=host   --env HIVE_CDN_ENDPOINT="http://IP:8082/artifacts/v1/08cda34e-9dc0-4c3b-90cc-1b7782bca97e"   --env HIVE_CDN_KEY="$TOKEN=="  --env HIVE_TOKEN="$SECRET" --env HIVE_CDN_ACCEPT_INVALID_CERTS="true" --env APOLLO_ROUTER_SUPERGRAPH_URLS="http://IP:8082/artifacts/v1/08cda34e-9dc0-4c3b-90cc-1b7782bca97e/supergraph" --env APOLLO_ROUTER_LOG="debug" --env HIVE_ENDPOINT="http://IP:8081/usage"   --mount "type=bind,source=/home/ec2-user/router.yaml,target=/dist/config/router.yaml" --rm -d --name=apollo-router ghcr.io/kamilkisiela/graphql-hive/apollo-router:latest```

and router.yaml file

```supergraph:
  listen: 0.0.0.0:4000
  introspection: true
plugins:
  hive.usage:
    {}
include_subgraph_errors:
  all: true
cors:
  allow_any_origin: true

health-check:
  listen: 0.0.0.0:8088
  enabled: true

homepage:
  enabled: false

sandbox:
  enabled: true

Any ideas guys?

Forgot to add @Component to the resolver :facepalm: