Types and Fields
Object types are the workhorses of a GraphQL schema. Almost everything a client touches is an object type with fields, and the way you choose those fields — their names, their types, the arguments they accept — is most of what schema design is. This lesson goes deep on the object type and the four things you can do with its fields.
Object types and their fields
Section titled “Object types and their fields”An object type is a named bundle of fields. Each field has a name and a type. Here is a type modelling a recipe in a cooking app:
type Recipe { id: ID! title: String! servings: Int! prepMinutes: Int}Recipe has four fields. Three of them resolve to scalars — an ID, a String, and two Int values — and the field’s type is a promise about what the client receives. A field name should read as a property of the thing: title, servings, prepMinutes. Prefer clear domain nouns over abbreviations; the schema is read far more often than it is written.
Field arguments
Section titled “Field arguments”A field can take arguments, just like a function parameter. Arguments let a single field serve many shapes of request. The classic use is a lookup field on the root Query type:
type Query { recipe(id: ID!): Recipe recipes(first: Int, search: String): [Recipe!]!}recipe takes a required id and returns one recipe (or null if none matches). recipes takes optional first and search arguments to page and filter a list. Arguments are not limited to root fields — any field can take them. A common pattern is letting a field reshape its own result:
type Recipe { id: ID! title: String! description(maxLength: Int): String}Here the client can ask for a truncated description by passing maxLength, and the resolver does the trimming. The argument lives on the field that uses it.
Descriptions — documentation in the schema
Section titled “Descriptions — documentation in the schema”GraphQL has documentation built in. Any type, field, or argument can carry a description written as a string literal directly above it. These descriptions show up in tooling, in GraphiQL, and in generated docs:
"""A single dish a user can cook, including timing and serving information."""type Recipe { "Stable unique identifier for the recipe." id: ID!
"Human-readable name shown in listings and headers." title: String!
"How many portions the recipe yields." servings: Int!}A triple-quoted block handles multi-line text; a single-quoted string suffices for one line. Descriptions are not decoration — they are part of the contract that humans read. Write them as if explaining the field to a developer who has never seen your domain.
Relationships — how types link into a graph
Section titled “Relationships — how types link into a graph”The moment a field’s type is another object type, your schema stops being a list of flat records and becomes a graph. A recipe has an author; an author has recipes:
type Recipe { id: ID! title: String! author: Author!}
type Author { id: ID! name: String! recipes: [Recipe!]!}The author field on Recipe points at the Author type, and the recipes field on Author points back. A client can start at a recipe, step into its author, and walk to that author’s other recipes — all in one query. These linking fields are the edges of your graph, and choosing them well is what makes an API feel cohesive.
flowchart LR Query["Query"] Recipe["type Recipe"] Author["type Author"] Args["Field arg: recipe(id: ID!)"] Query --> Args Args --> Recipe Recipe -->|"author"| Author Author -->|"recipes"| Recipe
Putting it together, run for real
Section titled “Putting it together, run for real”The example below defines Recipe and Author, gives the recipe field an argument, and runs a query that traverses the relationship between the two types. Press Run.
The query supplied id as an argument, received a single Recipe, then stepped into author and back out to that author’s recipe list. One round trip, several types — that is the graph at work.