All skills
apollographql avatar

/apollo-connectors

@55e7707 official
by Apollo GraphQLapollographql/skills115 stars
13

Guide for integrating REST APIs into GraphQL supergraphs using Apollo Connectors with @source and @connect directives. Use this skill when the user: (1) mentions "connectors", "Apollo Connectors", or "REST Connector", (2) wants to integrate a REST API into GraphQL, (3) references @source or @connect directives, (4) works with files containing "# Note to AI Friends: This is an Apollo Connectors schema".

Use this Skill: https://skilld.dev/gh/apollographql/skills/apollo-connectors

This session only. Nothing lands on disk.

referencesvalidation.md

≈2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Validation Commands

Table of Contents

Compose Schema

Validate that your schema composes correctly with rover supergraph compose.

rover supergraph compose --config ./supergraph.yaml

supergraph.yaml Template

federation_version must be the latest patch of the current Federation LTS. =2.15.2 is that patch today; confirm it against the version requirements before composing.

federation_version: =2.15.4
subgraphs:
  my-connector:  # Unique name for this subgraph
    routing_url: http://localhost  # Placeholder, ignored but required
    schema:
      file: schema.graphql  # Path to your connector schema

Multiple subgraphs:

federation_version: =2.15.4
subgraphs:
  users:
    routing_url: http://localhost
    schema:
      file: users.graphql
  products:
    routing_url: http://localhost
    schema:
      file: products.graphql
  orders:
    routing_url: http://localhost
    schema:
      file: orders.graphql

Common Composition Errors

Error Cause Solution
INVALID_BODY Literal object without $() Use body: "$({ a: $args.a })"
MISSING_ENTITY_CONNECTOR Entity without @connect Add @connect to the entity type
CIRCULAR_REFERENCE Entity stubs create a cycle Use @inaccessible foreign key pattern

Execute Connector

Test a single connector against the live API with rover connector run.

rover connector run \
  --schema schema.graphql \
  -c "Query.user" \
  -v '{ "$args": { "id": "123" } }'

Parameters

Parameter Description Example
--schema Path to schema file --schema schema.graphql
-c Target connector (Type.field or Type) -c "Query.user" or -c "User"
-v Variables as JSON -v '{ "$args": { "id": "1" } }'

Target Format

# Field-level connector
-c "Query.user"
-c "User.posts"

# Type-level connector
-c "User"

# Multiple connectors on same target (0-indexed)
-c "User[0]"
-c "User[1]"

Variable Format

Variables must include the $ prefix:

# $args
-v '{ "$args": { "id": "123", "limit": 10 } }'

# $this
-v '{ "$this": { "userId": "456" } }'

# $batch (array)
-v '{ "$batch": [{ "id": "1" }, { "id": "2" }] }'

# Combined
-v '{ "$args": { "limit": 10 }, "$this": { "userId": "123" } }'

Examples

Query with arguments:

rover connector run \
  --schema schema.graphql \
  -c "Query.user" \
  -v '{ "$args": { "id": "user-123" } }'

Field on type:

rover connector run \
  --schema schema.graphql \
  -c "User.posts" \
  -v '{ "$this": { "id": "user-123" } }'

Entity resolver:

rover connector run \
  --schema schema.graphql \
  -c "Product" \
  -v '{ "$this": { "id": "prod-456" } }'

Batch connector:

rover connector run \
  --schema schema.graphql \
  -c "Product" \
  -v '{ "$batch": [{ "id": "1" }, { "id": "2" }, { "id": "3" }] }'

Test Connector

Run automated tests with rover connector test.

rover connector test

This runs all *.connector.yaml test files found in the project.

Test File Location

Place test files in a /tests directory:

/tests/
  users.connector.yaml
  products.connector.yaml
  orders.connector.yaml

Test File Structure

config:
  schema: ../schema.graphql  # Path to schema file

tests:
  - name: "Should fetch user by ID"
    target: "Query.user"
    variables:
      $args:
        id: "user-123"
    apiResponseBody: |
      {
        "id": "user-123",
        "name": "John Doe",
        "email": "john@example.com"
      }
    expect:
      connectorRequest:
        url: http://api.example.com/users/user-123
      connectorResponse: |
        {
          "id": "user-123",
          "name": "John Doe",
          "email": "john@example.com"
        }

Test File Schema

config:
  schema: string          # Required: path to schema file
  name: string            # Optional: test suite name

tests:
  - name: string          # Required: test name
    target: string        # Required: Type.field or Type[index]
    skip: boolean         # Optional: skip this test
    variables:            # Optional: input variables
      $args: object
      $this: object
      $batch: array
      $context: object
      $config: object
      $requestHeaders: object
    apiResponseBody: string       # Mock API response (inline)
    apiResponseBodyFile: string   # Mock API response (file path)
    apiResponseHeaders: object    # Mock response headers
    status: integer               # Mock HTTP status code
    expect:
      connectorRequest:           # Expected request
        method: GET|POST|PUT|PATCH|DELETE
        url: string               # Preferred: full URL
        origin: string            # Alternative: only origin
        path: string              # Alternative: only path
        queryParams: object
        headers: object
        body: string
        bodyFile: string
      connectorResponse: string   # Expected mapped response (inline)
      connectorResponseFile: string  # Expected response (file path)
      error:                      # Expected error
        message: string
        extensions: object
      problems: array             # Expected problems

Test Examples

Basic query test:

tests:
  - name: "Get user by ID"
    target: "Query.user"
    variables:
      $args:
        id: "123"
    apiResponseBody: |
      { "id": "123", "name": "Alice" }
    expect:
      connectorRequest:
        url: http://api.example.com/users/123
      connectorResponse: |
        { "id": "123", "name": "Alice" }

Entity resolver test:

tests:
  - name: "Resolve User entity"
    target: "User"
    variables:
      $this:
        id: "456"
    apiResponseBody: |
      { "id": "456", "name": "Bob", "email": "bob@test.com" }
    expect:
      connectorRequest:
        url: http://api.example.com/users/456
      connectorResponse: |
        { "id": "456", "name": "Bob", "email": "bob@test.com" }

Batch connector test:

tests:
  - name: "Batch resolve products"
    target: "Product"
    variables:
      $batch:
        - id: "1"
        - id: "2"
    apiResponseBody: |
      [
        { "id": "1", "name": "Widget" },
        { "id": "2", "name": "Gadget" }
      ]
    expect:
      connectorRequest:
        method: POST
        url: http://api.example.com/products/batch
        body: '{"ids":["1","2"]}'
      connectorResponse: |
        [
          { "id": "1", "name": "Widget" },
          { "id": "2", "name": "Gadget" }
        ]

Test with headers:

tests:
  - name: "Request with auth header"
    target: "Query.protectedData"
    variables:
      $requestHeaders:
        authorization: "Bearer token123"
    apiResponseBody: |
      { "data": "secret" }
    expect:
      connectorRequest:
        url: http://api.example.com/protected
        headers:
          Authorization: "Bearer token123"
      connectorResponse: |
        { "data": "secret" }

Error handling test:

tests:
  - name: "Handle 404 error"
    target: "Query.user"
    variables:
      $args:
        id: "not-found"
    status: 404
    apiResponseBody: |
      { "error": "User not found" }
    expect:
      connectorRequest:
        url: http://api.example.com/users/not-found
      error:
        message: "User not found"
        extensions: {}

Important Notes

  1. connectorResponse is the result of selection mapping, NOT the final GraphQL response
  2. No type conversion happens unless explicitly done in the selection
  3. Prefer expect.connectorRequest.url over separate origin and path
  4. Test both success and error cases
  5. Ensure full coverage for each connector

Source: SKILL.md on GitHub

1 warning6d5 checks · Risk SAFE
  • Gen Agent Trust Hub6d

    The skill is a comprehensive documentation and assistance tool for Apollo Connectors. It adheres to security best practices by using environment variables for secret management, restricted command execution via the rover CLI, and fetching resources from official vendor domains.

  • Socket6d

    No alerts

  • Snyk6d

    Risk: LOW · No issues

  • Runlayer7mo

    7/7 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 55e7707. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated last week
What it can do
Runs commands
metadata
{
  "author": "apollographql",
  "version": "1.0.1"
}
All 1 allowed tools
Bash(rover:*) Read Write Edit Glob Grep
Other metadata
compatibility
Requires rover CLI installed. Works with Claude Code and similar AI coding assistants.
  • graphql
  • apollo
  • rest-api
  • connectors
  • federation
  • schema
  • integration

README badge

README badge for apollographql/skills/apollo-connectors

Integrates REST APIs into GraphQL supergraphs using Apollo Connectors with @source and @connect directives. Targets the rover CLI workflow and follows a five-step process: research the API, implement the schema, validate with rover compose, execute with rover connector run, and test coverage.

Generated from the current SKILL.md.

What versions of Apollo federation and connectors does this skill support?
The skill uses federation v2.12 and connect v0.3 by default unless you specify otherwise.
Do I need rover CLI installed to use this skill?
Yes. The skill requires rover CLI installed and uses commands like `rover supergraph compose`, `rover connector run`, and `rover connector test`.
Can this skill integrate any REST API into GraphQL?
Yes. The skill handles REST API integration using @source and @connect directives, supporting GET/POST requests, headers, batching, and response field mapping.
Does this skill handle entity relationships and N+1 query patterns?
Yes. The skill creates entity relationships when ID fields are present and converts N+1 patterns using batching with the $batch variable.
What happens if composition or connector execution fails?
The skill follows a 5-step validation process that runs `rover supergraph compose` after schema changes and `rover connector run` before testing, catching errors before they reach production.

Generated from the current SKILL.md. These answers refresh after source changes.