rust – Federated Entities with async-graphql

 

I’m struggling to figure out how to marry two different GraphQL objects together. In the PoC I’m putting together, I have an Invoice object:

#[derive(SimpleObject, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Invoice {
  invoice_no: String,
  invoice_date: NaiveDate,
  amount: Decimal,
  paid: bool,
  customer_no: i32
}

With the appropriate queries:

async fn invoice(
        &self,
        ctx: &Context<'_>,
        invoice_no: String,
    ) -> FieldResult<Invoice> {}

    async fn invoices(
        &self,
        ctx: &Context<'_>,
        start_date: Option<NaiveDate>,
        end_date: Option<NaiveDate>,
        customer_no: Option<i32>,
        paid: Option<bool>,
        after: Option<String>,
        before: Option<String>,
        first: Option<i32>,
        last: Option<i32>,
    ) -> Result<Connection<usize, Invoice, Summary, EmptyFields>> {}

This works exactly as expected when I start my application, and all the queries work correctly.

I have another application, but this one of Customer objects:

#[derive(SimpleObject, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Customer {
  customer_no: i32,
  city: String,
  name: String
}

It has similar queries to Invoice, but also includes:

#[graphql(entity)]
async fn find_customer_by_customer_no(
    &self,
    ctx: &Context<'_>,
    #[graphql(key)] customer_no: i32,
) -> FieldResult<Option<Customer>> {}

I also have a representation of an Invoice in this service to merge them together:

struct Invoice {
  customer_no: i32
}


#[Object(extends)]
impl Invoice {
    #[graphql(external)]
    async fn customer_no(&self) -> &i32 {
        &self.customer_no
    }
    
    async fn customer(&self, ctx: &Context<'_>) -> Option<Customer> {
      // Implementation
    }
}

Again, by itself, I can query all the customers perfectly. When I set up an Apollo federation gateway, I get a schema back that includes both Invoice and Customer queries. However, the customer field never gets added to the Invoice object. The Apollo gateway doesn’t report any errors on startup. What am I missing to add the field to the object?

Source link