Skip to content

GraphQL Integration

The Manager provides a comprehensive GraphQL API for programmatic access to all platform features.

Complete API Reference

See the API Reference for complete GraphQL schema documentation, all queries, mutations, and detailed examples.

Quick Start

Endpoint

POST http://your-manager-host:8080/query

GraphQL Playground

Interactive schema explorer (development mode only):

GET http://localhost:8080/gql

Authentication

Include authentication token in request headers:

http
Authorization: Bearer <your-token>

Use either:

  • Personal Access Token - For user actions
  • Machine User Token - For automated services

See Authentication for details.

Client Setup

JavaScript/TypeScript

javascript
const graphqlClient = async (query, variables = {}) => {
  const response = await fetch("http://localhost:8080/query", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.MANAGER_TOKEN}`,
    },
    body: JSON.stringify({ query, variables }),
  });

  const { data, errors } = await response.json();

  if (errors) {
    throw new Error(errors[0].message);
  }

  return data;
};

Python

python
import requests
import os

def graphql_client(query, variables=None):
    response = requests.post(
        'http://localhost:8080/query',
        json={'query': query, 'variables': variables or {}},
        headers={
            'Authorization': f'Bearer {os.getenv("MANAGER_TOKEN")}'
        }
    )

    result = response.json()

    if 'errors' in result:
        raise Exception(result['errors'][0]['message'])

    return result['data']

Go

go
package main

import (
    "bytes"
    "encoding/json"
    "net/http"
    "os"
)

type GraphQLRequest struct {
    Query     string                 `json:"query"`
    Variables map[string]interface{} `json:"variables,omitempty"`
}

func GraphQLClient(query string, variables map[string]interface{}) (map[string]interface{}, error) {
    reqBody, _ := json.Marshal(GraphQLRequest{
        Query:     query,
        Variables: variables,
    })

    req, _ := http.NewRequest("POST", "http://localhost:8080/query", bytes.NewBuffer(reqBody))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer "+os.Getenv("MANAGER_TOKEN"))

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)

    return result, nil
}

Common Patterns

Query with Variables

javascript
const query = `
  query GetTenant($projectId: ID!, $slug: String!) {
    tenant(projectId: $projectId, slug: $slug) {
      id
      name
      applications {
        id
        name
      }
    }
  }
`;

const data = await graphqlClient(query, {
  projectId: "project-123",
  slug: "my-tenant",
});

Create Resource

javascript
const mutation = `
  mutation CreateApplication($tenantId: ID!, $input: CreateApplicationInput!) {
    createApplication(tenantId: $tenantId, input: $input) {
      id
      name
      slug
    }
  }
`;

const result = await graphqlClient(mutation, {
  tenantId: "tenant-uuid",
  input: {
    name: "My App",
    slug: "my-app",
    description: "Application description",
  },
});

Error Handling

javascript
try {
  const data = await graphqlClient(query, variables);
  console.log("Success:", data);
} catch (error) {
  console.error("GraphQL Error:", error.message);
  // Handle specific error codes
  if (error.message.includes("NOT_FOUND")) {
    // Resource not found
  } else if (error.message.includes("UNAUTHORIZED")) {
    // Authentication failed
  }
}

Best Practices

Use Variables

Always use variables instead of hardcoding values:

javascript
// [NO] Avoid hardcoding
const query = `
  query {
    tenant(projectId: "abc-123", slug: "my-tenant") { name }
  }
`;

// [OK] Use variables
const query = `
  query GetTenant($projectId: ID!, $slug: String!) {
    tenant(projectId: $projectId, slug: $slug) { name }
  }
`;

const data = await graphqlClient(query, {
  projectId: "abc-123",
  slug: "my-tenant",
});

Request Only Needed Fields

GraphQL allows precise field selection - use it:

javascript
// [NO] Over-fetching
const query = `
  query {
    applications(tenantSlug: "tenant", filters: [], order: {...}, pagination: {...}) {
      id name slug description createdAt updatedAt
      tenant { id name slug type createdAt updatedAt }
      endpoints { id name url enabled createdAt }
      triggers { id name cronExpression enabled }
    }
  }
`;

// [OK] Request only what you need
const query = `
  query {
    applications(tenantSlug: "tenant", filters: [], order: {...}, pagination: {...}) {
      id
      name
    }
  }
`;

Use Fragments for Reusability

javascript
const fragments = `
  fragment ApplicationFields on Application {
    id
    name
    slug
  }
`;

const query = `
  ${fragments}
  query GetApplications($tenantSlug: String!) {
    applications(tenantSlug: $tenantSlug, filters: [], order: {...}, pagination: {...}) {
      ...ApplicationFields
    }
  }
`;

Handle Pagination

javascript
async function getAllApplications(tenantSlug) {
  const allApps = [];
  let offset = 0;
  const limit = 50;

  while (true) {
    const data = await graphqlClient(
      `
      query GetApplications($tenantSlug: String!, $limit: Int!, $offset: Int!) {
        applications(
          tenantSlug: $tenantSlug
          filters: []
          order: { field: "name", direction: ASC }
          pagination: { limit: $limit, offset: $offset }
        ) {
          id
          name
        }
      }
    `,
      { tenantSlug, limit, offset }
    );

    if (data.applications.length === 0) break;

    allApps.push(...data.applications);
    offset += limit;
  }

  return allApps;
}

GraphQL Tools

Apollo Client (JavaScript)

bash
npm install @apollo/client graphql
javascript
import { ApolloClient, InMemoryCache, gql } from "@apollo/client";

const client = new ApolloClient({
  uri: "http://localhost:8080/query",
  cache: new InMemoryCache(),
  headers: {
    authorization: `Bearer ${process.env.MANAGER_TOKEN}`,
  },
});

const { data } = await client.query({
  query: gql`
    query GetTenants($projectSlug: String!) {
      tenants(projectSlug: $projectSlug, filters: [], order: {...}, pagination: {...}) {
        id
        name
      }
    }
  `,
  variables: { projectSlug: "my-project" },
});

urql (React)

bash
npm install urql graphql
javascript
import { createClient, useQuery } from "urql";

const client = createClient({
  url: "http://localhost:8080/query",
  fetchOptions: {
    headers: {
      authorization: `Bearer ${process.env.MANAGER_TOKEN}`,
    },
  },
});

function TenantsList() {
  const [result] = useQuery({
    query: `
      query GetTenants($projectSlug: String!) {
        tenants(projectSlug: $projectSlug, filters: [], order: {...}, pagination: {...}) {
          id name
        }
      }
    `,
    variables: { projectSlug: "my-project" },
  });

  return <div>{/* render */}</div>;
}

See Also