Introduction to GraphQL
Learn the fundamental terminology and concepts for using Common Ground's GraphQL APIs. This guide will help you understand how GraphQL works and how to effectively use it with Common Ground.
What is GraphQL?
GraphQL is a query language for APIs and a runtime for executing those queries. Unlike REST APIs that expose multiple endpoints for different resources, GraphQL provides a single endpoint where you can request exactly the data you need.
Key Benefits
- Request Only What You Need: Fetch exactly the fields you require, reducing payload sizes
- Single Endpoint: Access all your data through one GraphQL endpoint
- Strongly Typed: Complete type system with schema validation
- Introspective: Query the schema to discover available operations
- Flexible: Combine multiple resources in a single request
GraphQL Terminology
Understanding GraphQL terminology will help you navigate the API documentation and write effective queries.
Schema
A schema defines a GraphQL API's type system. It describes the complete set of possible data (objects, fields, relationships) that a client can access. All queries and mutations are validated and executed against the schema.
The schema acts as a contract between the client and server, ensuring type safety and preventing invalid requests.
Field
A field is a unit of data you can retrieve from an object. The GraphQL query language is essentially about selecting fields on objects.
All GraphQL operations must specify their selections down to fields which return scalar values (strings, numbers, booleans, etc.). If you try to return a field that is not a scalar, you must add nested subfields until all fields return scalars.
Example:
# ✅ Valid - all fields return scalars
query {
item {
_id # String (scalar)
title # String (scalar)
price # Number (scalar)
}
}
# ❌ Invalid - missing subfields for nested object
query {
item {
_id
seo # This is an object, needs subfields!
}
}
# ✅ Valid - includes subfields for nested object
query {
item {
_id
seo {
title # String (scalar)
description # String (scalar)
}
}
}
Argument
An argument is a set of key-value pairs attached to a specific field. Some fields require arguments, while others accept optional arguments to filter, sort, or paginate results.
Example:
query {
# Field with required argument
item(id: "123") {
title
}
# Field with optional arguments
items(
pagination: { page: 1, limit: 20 }
filters: { type: "vinyl" }
) {
items {
title
}
}
}
Query
A query is a read operation that fetches data from the API. Queries are similar to GET requests in REST APIs, but with more flexibility.
Example:
query GetItems {
items(pagination: { page: 1, limit: 10 }) {
items {
_id
title
price
}
pagination {
page
pages
count
}
}
}
Key Points:
- Queries are read-only operations
- You can request multiple resources in a single query
- Queries can be nested to fetch related data
Mutation
A mutation is a write operation that modifies data on the server. Mutations are similar to POST, PUT, PATCH, or DELETE requests in REST APIs.
Example:
mutation CreateCollection($input: CollectionInput!) {
collectionCreate(input: $input) {
collection {
_id
title
}
}
}
Key Points:
- Mutations modify data (create, update, delete)
- Mutations require an input object as an argument
- Mutations return the modified data
Type
A type defines the structure of an object, including its fields and their types. Common Ground's GraphQL API includes many types like Item, Order, User, Collection, etc.
Example Type Definition:
type Item {
_id: ID!
id: Float!
title: String
price: Float
stock: Stock
seo: SeoEntry
}
Scalar
A scalar is a primitive value type. GraphQL comes with built-in scalars:
String- Text dataInt- Integer numbersFloat- Decimal numbersBoolean- True/false valuesID- Unique identifier (serialized as string)
Common Ground also uses custom scalars like:
Date- Date and time valuesJSON- Arbitrary JSON dataUpload- File uploads
Identifiers
Common Ground uses two types of identifiers for entities:
-
id- Business identifier (numeric or string)- Used as the primary parameter in queries and mutations
- Examples:
item(id: 12345),checkout(id: "abc123xyz") - This is the identifier you'll use most often
-
_id- Internal database identifier (ObjectId)- Returned in query responses as
_id: ID! - Used internally by the system
- Not typically used as a query parameter
- Returned in query responses as
-
*Refparameters - Reference to database_id- When you need to reference by
_idinstead ofid, use the*Refparameter - Examples:
itemRef,listingRef,orderRef,checkoutRef - Used in Admin API mutations when working with internal references
- When you need to reference by
When updating or referencing entities, use the
idfield (not_id) as the parameter. The_idfield is returned in responses but should not be used as input parameters.
Example:
# ✅ Correct - using 'id' parameter
query {
checkout(id: "abc123xyz") {
_id # This is returned in the response
id # This is the business identifier
status
}
}
# ✅ Correct - using 'itemRef' when you have the _id
mutation {
itemUpdate(itemRef: "507f1f77bcf86cd799439011", ...) {
_id
id
}
}
# ❌ Incorrect - don't use _id as a parameter
query {
checkout(_id: "507f1f77bcf86cd799439011") { # This won't work!
id
}
}
Common Patterns:
- Client API: Use
id(string) for checkouts and orders - Admin API: Use
id(numeric) for items, oritemRef/listingRefwhen you have the database_id - Both APIs: Always use the
idfield from responses for subsequent operations
Interface
An interface defines a set of fields that multiple types can implement. This allows you to query for common fields across different types.
Example:
interface ItemInterface {
_id: ID!
title: String
price: Float
}
type VinylRecord implements ItemInterface {
_id: ID!
title: String
price: Float
artist: String
label: String
}
When querying an interface, you can use inline fragments to access type-specific fields:
query {
items {
_id
title
... on VinylRecord {
artist
label
}
}
}
Union
A union type represents a value that can be one of several types. Unlike interfaces, unions don't require common fields.
Example:
union SearchResult = Item | Collection | Article
query {
search(query: "vinyl") {
... on Item {
title
price
}
... on Collection {
title
description
}
... on Article {
title
content
}
}
}
Input Object
An input object is used to pass complex data to mutations or queries. Input objects are similar to regular objects but are used only for input.
Example:
input CollectionInput {
title: String!
description: String
items: [ID!]
}
mutation CreateCollection($input: CollectionInput!) {
collectionCreate(input: $input) {
collection {
_id
title
}
}
}
Enum
An enum is a type that represents a fixed set of possible values.
Example:
enum OrderStatus {
PENDING
PROCESSING
SHIPPED
DELIVERED
CANCELLED
}
query {
orders(status: PENDING) {
_id
status
}
}
Common GraphQL Patterns
Selecting Specific Fields
Always specify exactly which fields you want to retrieve:
# ✅ Good - specific fields
query {
item(id: "123") {
_id
title
price
}
}
# ❌ Avoid - requesting everything (if supported)
# This is not how GraphQL works - you must specify fields
Nested Queries
GraphQL allows you to fetch related data in a single request:
query {
item(id: "123") {
_id
title
collection {
_id
title
items {
_id
title
}
}
}
}
Using Variables
Use variables to make queries reusable and avoid string interpolation:
query GetItem($itemId: ID!) {
item(id: $itemId) {
_id
title
price
}
}
Variables:
{
"itemId": "123"
}
Aliases
Use aliases to request the same field multiple times with different arguments:
query {
firstPage: items(pagination: { page: 1, limit: 10 }) {
items { title }
}
secondPage: items(pagination: { page: 2, limit: 10 }) {
items { title }
}
}
Fragments
Fragments let you reuse field selections:
fragment ItemFields on Item {
_id
title
price
stock {
quantity
}
}
query {
item(id: "123") {
...ItemFields
}
items {
items {
...ItemFields
}
}
}
Making Your First Query
Example query that fetches items with pagination:
query GetItems {
items(pagination: { page: 1, limit: 5 }) {
items {
_id
title
price
}
pagination {
page
pages
count
}
}
}
This query requests the items field with pagination arguments, selects specific fields (_id, title, price), and includes pagination metadata.
Response:
{
"data": {
"items": {
"items": [
{ "_id": "1", "title": "Item 1", "price": 29.99 },
{ "_id": "2", "title": "Item 2", "price": 39.99 }
],
"pagination": {
"page": 1,
"pages": 10,
"count": 50
}
}
}
}
Understanding the Schema
Schema Introspection
GraphQL is introspective by design, meaning you can typically query the schema to discover available types and operations. However, Common Ground APIs do not allow introspection queries for security and performance reasons.
Instead, you can use the downloadable schema files to explore the complete API structure. These schema files contain all the information you would get from introspection queries, including type definitions, field descriptions, and available operations.
Downloadable Schemas
For the most complete and up-to-date schema information, download the schema files:
- Admin API Schema - Complete schema for backend operations
- Client API Schema - Complete schema for frontend operations
These schema files can be used with:
- GraphQL code generators (GraphQL Code Generator, Apollo Codegen)
- IDE plugins for autocomplete and validation
- Documentation tools
- Type-safe client libraries
Best Practices
- Request only what you need - Select only the fields you require to reduce payload size and improve performance
- Use descriptive query names - Name queries and mutations clearly (e.g.,
GetUserProfileinstead ofQuery1) - Use variables - Always use variables instead of hardcoding values to make queries reusable and secure
- Handle errors - Check for errors in responses even when HTTP status is 200. See Handling Errors for details
- Use fragments for reusability - Create fragments for commonly used field selections to avoid repetition
Next Steps
- Working with Queries - Learn how to write and execute queries
- Working with Mutations - Learn how to create, update, and delete data
- Paginating - Learn how to paginate through large datasets
- Filtering Data - Learn how to filter and sort your queries
- Handling Errors - Understand how errors work in GraphQL
- Developing - Tools, clients, and best practices
Additional Resources
- GraphQL Official Documentation - Comprehensive GraphQL learning resources
- GraphQL Specification - The official GraphQL specification
- Common Ground Admin API Schema - Download the Admin API schema
- Common Ground Client API Schema - Download the Client API schema
Ready to start querying? Check out the Admin API Quick Start or Client API Quick Start to make your first API call.