Odyssey

Agentic GraphQL: MCP for the Enterprise
beta

MCP and GraphOSProject setupThe Apollo Runtime ContainerPersisted queriesIntrospection and contracts
5. Introspection and contracts
9m

Overview

Sometimes predefined tools won't suffice when our AI assistant is faced with new user requests. Let's give the assistant another option!

In this lesson, we will:

  • Enable introspection in the MCP server
  • Set up a contract in GraphOS

GraphQL introspection

We can use the process of introspection to learn more about a graph's schema and the types of queries that can be executed. An introspection query is a special kind of query that we send for exactly this information.

Introspection is powerful because it permits users or assistants to create their own queries, which can address their needs or questions more precisely than predefined queries.

When faced with a user request, an AI assistant can take a look at the graph's schema and create the most relevant and precise query needed to resolve the request. But introspection comes with a downside: by providing all the details about a schema, we might inadvertently introduce security concerns. Bad actors can end up seeing more than they should, which can result in unauthorized queries being executed against the graph.

We want to be able to control how much of the schema an assistant can access. This lets us fine-tune how much of the graph we're exposing, while still giving the assistant the flexibility to create queries in the moment they're needed!

We'll start by exploring how we enable introspection in our MCP server, then look into how we can govern and secure it.

Enabling introspection

Using the Apollo Runtime Container, we can enable introspection by passing another environment variable: MCP_INTROSPECTION.

Let's stop our container, and add the new flag to our command before restarting it.

docker run \
--env APOLLO_GRAPH_REF=<YOUR GRAPH REF> \
--env APOLLO_KEY=<YOUR APOLLO KEY> \
--env MCP_ENABLE=1 \
--env MCP_UPLINK=1 \
--env MCP_INTROSPECTION=1 \
--rm -p 4000:4000 -p 5000:5000 \
ghcr.io/apollographql/apollo-runtime:latest

Next, we'll restart Claude to refresh its connection to our server.

Task!

Back in our chat interface, we should see that our airlock tools have increased in number to include execute as well as introspect: this is because we've given Claude to both introspect from our schema (in the process, devising its own queries) as well as execute them.

A screenshot of Claude, with two new tools added to the dropdown

Let's ask a broader question that prompts Claude to reason about the data it might need to request.

What can you tell me about Airlock's hosts?

Though this process is not deterministic (we can't say for sure what Claude will do), we might see a dialog box asking for permission to use an external integration.

A screenshot of Claude, with two new tools added to the dropdown

And because we've enabled introspection, we might very well see that Claude's requesting an introspect action; in other words, Claude is asking if it can learn more about our schema to determine exactly what it needs to request next. If we approve this request, pretty soon we're likely to see another. Claude has used the information it compiled about our schema to put together a new query, one that requests precisely the information we're after. (Of course, you might see Claude choose to use one of its available tools instead!)

Try out some other questions: see if you can challenge Claude to introspect more information from the schema to create its next queries to answer your questions!

Introducing contracts

Our setup currently includes our three persisted queries, as well as the ability for Claude to introspect any other information it might need from the schema. And as we mentioned earlier in this lesson, opening up your entire graph so that anyone can introspect it is not a great idea. To mitigate this security risk, we can define a specific subset of our schema to open up for introspection. We do this in GraphOS using contracts.

A contract defines the exact pieces of a schema that are accessible by a certain graph variant. We can create different graph variants, consisting of different types and fields from our schema, for different clients. This allows us to expose certain functionality only to those with the authorization to perform particular tasks. So while we won't give our AI assistants admin-level access to our graph and all its possible operations, we can define a reliable and safe section of the schema that Claude can access and use to come up with its own queries.

Creating a contract

Check your plan: This course includes features that are only available on the following GraphOS plans: Developer, Standard, or Enterprise.

Let's return to our graph in Studio. We can access the Contracts menu by navigating to our graph's Settings.

On the main tab (labelled This Variant (current)), we should see an option in the side menu called Contracts.

Clicking this, we'll find that we have... 0 contracts! Let's click the button there labeled Create contract.

A screenshot of Studio, highlighting the Contracts menu option as well as the Create contract button

Note: We're creating this contract based on our graph's only variant, which we refer to as "current". You can alternatively create a new variant of the graph (such as "mobile" or "partner", depending on who the contract will serve) by clicking to the This graph tab and selecting the Variants menu item. See the official documentation for step-by-step guidance on this process.

We'll see a modal open up where we can provide all our contract details. Let's give this contract the name "assistant", to make it clear that it's intended for AI assistant consumers of the graph. We'll keep the Source Variant set to our graph's only variant, "current".

A screenshot of Studio, with the Create contract modal opened and the details filled in

The next step takes us to Contract Filters. These are the rules that we apply to decide what is included and excluded from our resulting contract schema. We do this by specifying particular tags.

Tags are little extra bits of text we can append to the types and fields in our schema, kind of like annotations. On their own, they don't have any effect; but when we filter based on tags, GraphOS can include or exclude particular portions of the final schema.

Our schema doesn't actually contain any tags yet; we'll add those after. For now, let's say that we want our contract to filter out any of those fields we end up marking with a tag called "internal".

In the "Excluded tags" section, add a tag called internal.

A screenshot of Studio, showing the "internal" tag being added to the excluded list

Down at the bottom of the modal, we'll click the Generate Preview button.

The contract filters modal, highlighting the Generate Preview button

This takes into account the tags that we filtered on, and generates a preview of the schema that will be included in our contract. And... we shouldn't see any difference at all! Our Source Schema and Proposed Contract Schema should be exactly the same. Nothing in the schema has been tagged with "internal" yet, so nothing has been filtered out.

The contract filters modal, highlighting the schema preview without any differences

Let's click Review to jump to the next step.

On this next screen we'll have a chance to preview the resulting schema line-by-line. We won't see anything different here yet, so let's click the Create button. We'll see a final summary of our contract details. Hit View launch details.

A screenshot of the modal showing contract creation success

When Studio reloads, we'll find in our graph dropdown that we're now looking at the new contract variant that we created. We can always switch back to our current variant by selecting it from the dropdown, but for now we'll stay here so we can see our changes reflected when we update the schema.

The Launches page in Studio, highlighting the Contract variant we're on

Now let's jump into our schema file locally, and apply that "internal" tag to a few fields so we can see our contract actually at work.

Applying tags

Returning to your code editor, open up the src/schema.graphql file. The first thing we need to do is find our Federation imports at the top of the file and add "@tag" to the array.

schema.graphql
extend schema
@link(
url: "https://specs.apollo.dev/federation/v2.9"
import: ["@key", "@shareable", "@external", "@tag"]
)

In addition to our querying functionality, this schema also includes the types needed to create new listings. These look like good candidates for "internal"-only functionality, so let's take some time to attach our "internal" tag.

Jump down first to the Mutation type. It has two fields, createListing and updateListing, so we can apply our tag to the type as a whole. We do this by first specifying @tag, then passing a pair of parentheses that hold the tag's name value.

type Mutation @tag(name: "internal") {
"Creates a new listing"
createListing(listing: CreateListingInput!): CreateListingResponse!
updateListing(
listingId: ID!
listing: UpdateListingInput!
): UpdateListingResponse!
}

When we filter out those types and fields marked with "internal", this entire type will be removed from the resulting schema for our assistant contract variant. This means that our AI assistant won't be able to create or update listings, which is exactly what we want!

Let's do the same for both input types, CreateListingInput and UpdateListingInput.

input CreateListingInput @tag(name: "internal") {
"The listing's title"
title: String!
# ... other fields
}
"Updates the properties included. If none are given, don't update anything"
input UpdateListingInput @tag(name: "internal") {
"The listing's title"
title: String
# ... other fields
}

As well as both response types, CreateListingResponse and UpdateListingResponse.

type CreateListingResponse implements MutationResponse @tag(name: "internal") {
"Similar to HTTP status code, represents the status of the mutation"
code: Int!
# ... other fields
}
type UpdateListingResponse implements MutationResponse @tag(name: "internal") {
"Similar to HTTP status code, represents the status of the mutation"
code: Int!
# ... other fields
}

We could also apply these tags field-by-field: for instance, we could make any individual field on the Listing or Amenity types "internal"-only with our tag. But these types look good for now, so let's push up our schema changes.

extend schema
@link(
url: "https://specs.apollo.dev/federation/v2.7"
import: ["@key", "@shareable", "@external", "@tag"]
)
"""
Listing Graph
"""
type Query {
"A curated array of listings to feature on the homepage"
featuredListings: [Listing!]!
"Search results for listings that fit the criteria provided"
searchListings(criteria: SearchListingsInput): [Listing!]!
"Return the listings that belong to the currently logged-in host"
hostListings: [Listing!]!
"Returns the details about this listing"
listing(id: ID!): Listing
"Returns all possible amenities for a listing"
listingAmenities: [Amenity!]!
}
type Mutation @tag(name: "internal") {
"Creates a new listing for the currently authenticated host"
createListing(listing: CreateListingInput!): CreateListingResponse!
"Updates an existing listing"
updateListing(
listingId: ID!
listing: UpdateListingInput!
): UpdateListingResponse!
}
interface MutationResponse @tag(name: "internal") {
"Similar to HTTP status code, represents the status of the mutation"
code: Int!
"Indicates whether the mutation was successful"
success: Boolean!
"Human-readable message for the UI"
message: String!
}
type Listing @key(fields: "id") {
id: ID!
"The listing's title"
title: String!
"The listing's description"
description: String!
"The thumbnail image for the listing"
photoThumbnail: String!
"Photo edited for homepage"
photoInHexagonShape: String @deprecated(reason: "Unused field.")
"The number of beds available"
numOfBeds: Int!
"The cost per night"
costPerNight: Float!
"The location type of the listing"
locationType: LocationType!
"Owner of the listing"
host: Host!
"The amenities available for this listing"
amenities: [Amenity]!
"Where this listing is located in the galaxy"
coordinates: GalacticCoordinates
}
"Coordinates in the galaxy"
type GalacticCoordinates @shareable {
latitude: Float!
longitude: Float!
nickname: String
}
type Amenity {
id: ID!
category: AmenityCategory!
name: String!
}
enum AmenityCategory {
ACCOMMODATION_DETAILS
SPACE_SURVIVAL
OUTDOORS
}
enum LocationType {
SPACESHIP
HOUSE
CAMPSITE
APARTMENT
ROOM
}
input SearchListingsInput {
checkInDate: String!
checkOutDate: String!
numOfBeds: Int
page: Int
limit: Int
sortBy: SortByCriteria
}
enum SortByCriteria {
COST_ASC
COST_DESC
RATING_DESC
}
input CreateListingInput @tag(name: "internal") {
"The listing's title"
title: String!
"The listing's description"
description: String!
"The thumbnail image for the listing"
photoThumbnail: String!
"The number of beds available"
numOfBeds: Int!
"The cost per night"
costPerNight: Float!
"The location type of the listing"
locationType: LocationType!
"The Listing's amenities "
amenities: [ID!]!
}
"Updates the properties included. If none are given, don't update anything"
input UpdateListingInput @tag(name: "internal") {
"The listing's title"
title: String
"The listing's description"
description: String
"The thumbnail image for the listing"
photoThumbnail: String
"The number of beds available"
numOfBeds: Int
"The cost per night"
costPerNight: Float
"The location type of the listing"
locationType: LocationType
"The Listing's amenities "
amenities: [ID]
}
type CreateListingResponse implements MutationResponse @tag(name: "internal") {
"Similar to HTTP status code, represents the status of the mutation"
code: Int!
"Indicates whether the mutation was successful"
success: Boolean!
"Human-readable message for the UI"
message: String!
"The newly created listing"
listing: Listing
}
type UpdateListingResponse implements MutationResponse @tag(name: "internal") {
"Similar to HTTP status code, represents the status of the mutation"
code: Int!
"Indicates whether the mutation was successful"
success: Boolean!
"Human-readable message for the UI"
message: String!
"The newly created listing"
listing: Listing
}
type Host @key(fields: "id", resolvable: false) {
id: ID!
}

Publishing schema changes

We'll use the rover subgraph publish command to push our changes to our supergraph in GraphOS. Open up a new terminal window and run the command.

rover subgraph publish <YOUR GRAPH REF> \
--name listings --schema ./src/schema.graphql

Be sure to swap in your own unique graph ref before running the command. (And note that we're still publishing our changes to the current variant of our graph!)

We don't need to include the --routing-url argument in this command because we've already set that value, and we're not changing it to a new value.

Checking our changes

Now we can return to Studio to check out how our contract schema has changed. Make sure you've selected the "assistant" variant from the graph dropdown at the top of the screen. Select Schema from the side menu to see the types and fields this contract has access to.

No Mutation type here! Additionally, we won't find the Create and Update types we applied our tag to.

https://studio.apollographql.com

The Schema for our contract variant, showing the Mutation type has been filtered out

Now let's put this to the test in our assistant.

Testing in Claude

We've set up our contract, but our running Docker process is still based on our graph's current variant: which doesn't have any restrictions on what can be introspected.

Before changing our configuration, let's test the limits of what Claude can see and do in our system. Returning to the chat interface, let's see what it comes up with when we ask whether it's possible to create listings.

Can you check if you're able to create listings on Airlock?

Note: Asking Claude to explicitly check what capabilities it can perform is often the best way to trigger the "introspect" operation.

We'll likely see Claude request to use an external integration, specifically its introspect tool.

A screenshot of Claude asking for permission to run its introspect tool on the schema

And in response, we might see something like the following.

A screenshot of Claude listing out the different actions it can perform on Airlock

Now let's tell Claude to create a listing.

Can you create a new arctic-themed listing?

As we've already seen several times, Claude will likely prompt us to approve its use of one (or more) external integrations to resolve our request. And with that, we should see new listings created on the fly!

A screenshot of Claude sending a success message in regards to creating a new arctic-themed listing

If Claude created the new listing, and then tried to query for all of its details (including the host ID), it's more than likely our AI assistant ran into a problem. There's missing data in our backend: we didn't attach any particular host to the new listing when we created it, so now we hit a deadend when we request this data.

Claude might very well recover on its own here: it might attempt a different query that omits that problematic missing field. Try creating another listing afterward: does Claude automatically recover and use the new, fully-functional query? That's the power of our AI assistant, hooked into GraphQL! Flexibility at our fingertips, without the deadends of missing details.

Great, so we can see that creating listings works—that's great in development mode, but we probably need some better safeguards when we're in production, otherwise anyone—including their AI assistants—could bombard us with false listings. Now's the time to return to our contract!

Running the contract router

To connect Claude to our limited contract schema, rather than our full graph, we can update our Docker process. Right now we're running our router with the full schema; we passed in our current variant when we launched the process, which doesn't have any restrictions on included fields at all. We need to stop the process and then tweak the variant we're running to point to our assistant contract variant instead.

Return to the terminal where your Docker process is running, and stop it. We'll replace the @current variant name with @assistant.

docker run \
--env APOLLO_GRAPH_REF=<YOUR GRAPH NAME>@assistant \
--env APOLLO_KEY=<YOUR APOLLO KEY> \
--env MCP_ENABLE=1 \
--env MCP_UPLINK=1 \
--env MCP_INTROSPECTION=1 \
--rm -p 4000:4000 -p 5000:5000 \
ghcr.io/apollographql/apollo-runtime:latest

Your resulting APOLLO_GRAPH_REF value should look something like airlock-mcp@assistant.

Boot up the process, then let's restart Claude.

Task!

Back in the chat interface, we won't see anything different. But let's try that same path of inquiry we used before.

Can you check if you're able to create listings on Airlock?

We've still enabled introspection for our MCP server, so it's likely we'll see Claude ask for permission to use its introspect integration. But now, with our assistant contract variant filtering our mutation fields, Claude shouldn't be able to find anything about mutations or creating new listings!

A screenshot of Claude confirming that it cannot create new listings

We've locked off functionality—with just a few tags in our schema!

Practice

What is the main advantage of enabling introspection on your graph for AI assistants?
What is a potential risk of enabling full introspection on a production graph?
True or False: Contracts allow you to expose only a subset of your schema to specific clients or tools.

Key takeaways

  • Introspection allows AI assistants to generate queries based on the schema, but can introduce security risks.
  • Contracts let you define subsets of the schema that are accessible to specific clients or tools.
  • By applying @tag to schema types and fields, you can control what is included or excluded in a contract.
  • Enabling introspection and contracts together allows for flexible yet secure interactions with the graph.

Conclusion

Congratulations! You've leveled up your AI assistant interactions with the graph—without compromising security or governance. With persisted queries, we defined queries that could be exposed over MCP to our AI assistants as tools; and with introspection and contracts working in tandem, we could isolate particular pieces of the schema to give AI assistants access to. This granted them greater flexibility in creating new queries, without compromising our sensitive backend details.

Where else can you take your MCP & GraphQL interactions? What would you like to see next? Keep us posted in the comments, or reach out to the broader Apollo Community. Thanks for joining us here on Odyssey, and we hope to see you in the next one!

Previous

Share your questions and comments about this lesson

This course is currently in

beta
. Your feedback helps us improve! If you're stuck or confused, let us know and we'll help you out. All comments are public and must follow the Apollo Code of Conduct. Note that comments that have been resolved or addressed may be removed.

You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.

              introspection

              A special GraphQL query that enables clients and tools to fetch a GraphQL server's complete schema. Introspection should be disabled in production.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              GraphOS

              A platform for building and managing a supergraph. It provides a management plane to test and ship changes and runtime capabilities to secure and monitor the graph.

              introspection

              A special GraphQL query that enables clients and tools to fetch a GraphQL server's complete schema. Introspection should be disabled in production.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              Introspection

              A special GraphQL query that enables clients and tools to fetch a GraphQL server's complete schema. Introspection should be disabled in production.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              introspection

              A special GraphQL query that enables clients and tools to fetch a GraphQL server's complete schema. Introspection should be disabled in production.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              introspection

              A special GraphQL query that enables clients and tools to fetch a GraphQL server's complete schema. Introspection should be disabled in production.

              introspection

              A special GraphQL query that enables clients and tools to fetch a GraphQL server's complete schema. Introspection should be disabled in production.

              introspection

              A special GraphQL query that enables clients and tools to fetch a GraphQL server's complete schema. Introspection should be disabled in production.

              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              persisted queries

              A technique used to optimize GraphQL requests by storing operations. Clients send operation identifiers instead of full operations, reducing payload size.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              introspection

              A special GraphQL query that enables clients and tools to fetch a GraphQL server's complete schema. Introspection should be disabled in production.

              GraphOS

              A platform for building and managing a supergraph. It provides a management plane to test and ship changes and runtime capabilities to secure and monitor the graph.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              operations

              A single query, mutation, or subscription that clients send to a GraphQL server to request or manipulate data.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              contracts

              A mechanism for delivering different subsets of your supergraph to different consumers.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              GraphOS

              A platform for building and managing a supergraph. It provides a management plane to test and ship changes and runtime capabilities to secure and monitor the graph.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              querying

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              supergraph

              A unified, federated graph composed of separate GraphQL APIs using Apollo Federation. Enables a microservices architecture that exposes a unified GraphQL API to clients.

              GraphOS

              A platform for building and managing a supergraph. It provides a management plane to test and ship changes and runtime capabilities to secure and monitor the graph.

              graph ref

              A unique identifier for a particular variant of a particular graph in GraphOS. Made up of a graph's unique ID and variant name with the following format: graph-id@variant-name.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              argument

              A key-value pair associated with a particular schema field that lets operations pass data to that field's resolver.

              Argument values can be hardcoded as literal values (shown below for clarity) or provided via GraphQL variables (recommended).

              query GetHuman {
              human(id: "200") {
              name
              height(unit: "meters")
              }
              }
              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              operation

              A single query, mutation, or subscription that clients send to a GraphQL server to request or manipulate data.

              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              GraphQL

              An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              router

              The single access point for a federated GraphQL architecture. It receives incoming operations and intelligently routes them across component services before returning a unified response.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              launched

              The process of applying a set of updates to a supergraph. Launches are usually triggered by making changes to one of your published subgraph schemas.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              introspection

              A special GraphQL query that enables clients and tools to fetch a GraphQL server's complete schema. Introspection should be disabled in production.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              variant

              Independent instances of a graph often used to represent different environments. Each variant has its own schema and own router.

              mutation

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              mutations

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              Introspection

              A special GraphQL query that enables clients and tools to fetch a GraphQL server's complete schema. Introspection should be disabled in production.

              Contracts

              A mechanism for delivering different subsets of your supergraph to different consumers.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              introspection

              A special GraphQL query that enables clients and tools to fetch a GraphQL server's complete schema. Introspection should be disabled in production.

              contracts

              A mechanism for delivering different subsets of your supergraph to different consumers.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              persisted queries

              A technique used to optimize GraphQL requests by storing operations. Clients send operation identifiers instead of full operations, reducing payload size.

              introspection

              A special GraphQL query that enables clients and tools to fetch a GraphQL server's complete schema. Introspection should be disabled in production.

              contracts

              A mechanism for delivering different subsets of your supergraph to different consumers.

              GraphQL

              An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.

              Odyssey

              Apollo's official learning platform, featuring interactive tutorials, videos, code challenges, and certifications.

              NEW COURSE ALERT

              Introducing Apollo Connectors

              Connectors are the new and easy way to get started with GraphQL, using existing REST APIs.

              Say goodbye to GraphQL servers and resolvers—now, everything happens in the schema!

              Take the course