am00100
am00100

Reputation: 91

Representing calculations/script functions in GraphQL queries and schema

We are using GraphQL as a query language for a data aggregation engine.

I am looking for ideas to represent simple (or complex) arithmetic calculation functions in GraphQL referring to existing types/attributes defined in a schema, and can be used over existing attributes.

I am looking into Custom scalars and Directives

Example -

{
    item{
        units
        price_per_unit
        market_price: function:multiply(units, price_per_unit)
        market_price_usd: function:usdPrice(units, price_per_unit, currency)
    }
}

where function:multiply is already defined in the GraphQL schema as a type

functions {
    multiply(operand 1, operand2) {
        result
    }
    usdPrice(operand1, operand2, currency) {
        result: {
                if(currency == GBP) {
                    operand1 * operand2 * .76
                }
            {
    }

internally resolver will multiply operand 1 and operand 2 to create result.

Upvotes: 9

Views: 4873

Answers (1)

David Maze
David Maze

Reputation: 159750

This isn't something GraphQL is especially good at. By far the easiest thing to do will be to retrieve the individual fields and then do the computation on the client, something like

data.item.forEach((i) => { i.total_price = i.units * i.price_per_unit });

In particular, there's no way to run any sort of "subquery" in GraphQL. Given a "multiply" function like you've shown there's no GraphQL syntax that will let you "call" it with any particular inputs.

If you think the specific computed values are common enough, you can also add them to the GraphQL schema, and compute them server-side if requested using a custom resolver function.

type Item {
  units: Int!
  pricePerUnit: CurrencyValue!
  # computed, always units * pricePerUnit
  marketPrice: CurrencyValue!
}
type CurrencyValue {
  amount: Float!
  currency: Currency!
  # computed, always amount * currency { usd }
  usd: Float!
}
type Currency {
  code: String!
  "1 currency = this many US$"
  usd: Float!
}

allowing queries like

{
  item {
    marketPrice { usd }
  }
}

Upvotes: 1

Related Questions