graphprotocol / graph-node

Graph Node indexes data from blockchains such as Ethereum and serves it over GraphQL
https://thegraph.com
Apache License 2.0
2.91k stars 969 forks source link

Support for inline objects and lists of inline objects #927

Open Jannis opened 5 years ago

Jannis commented 5 years ago

Motivation / Rationale

We currently don't support inline objects: GraphQL types that are not entities and that be embedded in parent objects instead of referencing them via their IDs.

This feature is necessary to better support Ethereum tuples and arrays of Ethereum tuples in the GraphQL schema and particularly in graph init --from-contract scaffolding.

Imagine a contract has an event like the following

struct Receiver {
  address account,
  string name,
}

struct Details {
  uint256 amount,
  address token,
}

event MultiTransfer(
  address from,
  Receiver[] receivers,
  Details details,
)

We currently can't represent Receiver[] in the GraphQL schema and we represent Details by unrolling the fields into a flat list of fields:

type MultiTransfer @entity {
  id: ID!
  from: Bytes!
  // Receivers[] cannot be represented
  details_amount: BigInt!
  details_token: Bytes!
}

What we really want is this:

type Receiver {
  id: ID!
  account: Bytes!
  name: String!
}

type Details {
  amount: BigInt!
  token: Bytes!
}

type MultiTransfer @entity {
  from: Bytes!
  receivers: [Receiver!]!
  details: Details!
}
leoyvens commented 5 years ago

@Jannis Have we considered the possibility of having the tuple type be an entity, and generating the scaffolding code to handle it as such?

Inline objects are a possibility, but it introduces a special case in query execution, in the runtime and in the general mental model. This sounds like something we'll want eventually, possibly due to different performance characteristics, but for now having those be entities could be the simplest way to support tuple arrays in scaffolding.