Hypi data modelling
Hypi models are defined using GraphQL. For detailed documentation on what GraphQL is, consult the GraphQL documentation. In summary, it is a data definition and query language. It defines a type system used for modelling a domain and functions for working with the models in that domain.
Introduction to GraphQL
For the purposes of Hypi, we will discuss only the GraphQL features supported. GraphQL operations fall under three broad categories queries, mutations and subscriptions. Its type system consists of scalars and composites. Composites are further broken down into output and input types.
GraphQL by example
It can be useful to have a practical example to work with, let's imagine we're developing a simple inventory app. We will define the basic models that may be used and use them to demonstrate how it fits in with Hypi.
As a developer of the inventory app you could create a simple model such along these lines:
type Inventory {
name: String!
items: [Item!]!
}
type Item {
name: String!
sku: String
description: String @field(indexed: true)
price: Float!
}
A non-standard GraphQL thing appear in this model. The @field takes an indexed argument, if set to true, the field will become searchable i.e. you will be able to find records by searching the contents of this field. Any number of fields can be indexed. The exact mechanism by which you can search is discussed later.
Hypi will generate several things from this model. By default, Hypi does not generate a Relay pagination API but you can use the @withrelay directive on a type to have it generate a relay and apollo compatible version of your model. From the this model, the following are generated:
type Inventory {
name: String!
id: IDPK
hypi: Hypi
items(first: Int after: String): ItemConnection
}
type IDPK {
value: ID
publisherRealm: String
instanceRealm: String
version: String
}
type ItemConnection {
pageInfo: PageInfo!
edges: [ItemEdge]
}
type ItemEdge {
node: Item
cursor: String
}
#this type is not generated, it is provided by Hypi but included here for completeness
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
}
type InventoryInput {
id: ID
name: String!
items: [ItemInput!]!
}
type ItemInput {
id: ID
name: String!
sku: String
description: String
price: Float!
}
type InventoryInputOpt {
id: ID
name: String
items: [ItemInputOpt]
}
type ItemInputOpt {
id: ID
name: String
sku: String
description: String
price: Float
}
Query {
getInventory(id: ID!): Inventory
getSomeInventory(ids: [ID!]!): [Inventory!]!
findInventory(filter: String first: Int after: String): InventoryConnection!
}
Mutation {
trashInventory (ids: [ID]): Boolean
deleteInventory(ids: [ID]): Boolean
createInventory(value: InventoryInput): Inventory
updateInventory(value: InventoryInputOpt): Inventory
}
By going through this generated version of the inventory model, it should be clear as to what Hypi is doing.