Skip to content

Library HTTP Mode

Wallace Ricardo edited this page Apr 11, 2026 · 2 revisions

Library: HTTP Mode

HTTP mode lets you build a Go CLI that wraps any external GraphQL API. It connects over HTTP and registers standard gqlcli commands (query, mutation, batch, types, queries, mutations) on a urfave/cli application.

When to Use This

  • You want a CLI to query an existing GraphQL API
  • The API is remote or running as a separate process
  • You want to ship a CLI tool for API testing, CI/CD, or development workflows

For an in-process CLI that runs without an HTTP server, see Library-Inline-Mode.

Setup

go get github.com/wricardo/gqlcli

Basic Example

package main

import (
	"log"
	"os"

	"github.com/urfave/cli/v2"
	gqlcli "github.com/wricardo/gqlcli/pkg"
)

func main() {
	cfg := &gqlcli.Config{
		URL:     "http://localhost:8080/graphql",
		Format:  "toon",
		Timeout: 30,
	}

	builder := gqlcli.NewCLIBuilder(cfg)
	app := &cli.App{
		Name:  "gql",
		Usage: "GraphQL CLI for my API",
	}

	builder.RegisterCommands(app)

	if err := app.Run(os.Args); err != nil {
		log.Fatal(err)
	}
}

This gives you:

gql query '{ users { id name } }'
gql mutation 'mutation { createUser(name: "Alice") { id } }'
gql queries
gql mutations --filter user
gql types --kind OBJECT

Config Options

cfg := &gqlcli.Config{
	URL:     "https://api.example.com/graphql",  // Default endpoint
	Format:  "toon",                              // Default output format
	Timeout: 30,                                  // HTTP timeout in seconds
}

Users can still override URL with the --url flag or GRAPHQL_URL env var at runtime.

Adding Authentication

Pass auth headers via the config or let users supply them via .gqlcli.json:

cfg := &gqlcli.Config{
	URL: "https://api.example.com/graphql",
	Headers: map[string]string{
		"Authorization": "Bearer " + os.Getenv("API_TOKEN"),
	},
}

Alternatively, document .gqlcli.json usage for your users so they manage their own tokens. See Configuration.

Custom Formatter

Register a custom output format before building commands:

package main

import (
	"encoding/csv"
	"strings"

	gqlcli "github.com/wricardo/gqlcli/pkg"
)

type CSVFormatter struct{}

func (f *CSVFormatter) Format(data map[string]interface{}) (string, error) {
	var sb strings.Builder
	w := csv.NewWriter(&sb)
	// ... write rows from data ...
	w.Flush()
	return sb.String(), nil
}

func (f *CSVFormatter) Name() string {
	return "csv"
}

Then register it:

registry := gqlcli.NewFormatterRegistry()
registry.Register("csv", &CSVFormatter{})

cfg := &gqlcli.Config{URL: "...", Format: "toon"}

// NOTE: The stock CLIBuilder currently constructs its own formatter registry.
// To make a custom registry the default, either:
//   - wrap the CLIBuilder and call your formatter directly, or
//   - open a feature request to support injecting a custom registry.
_ = registry
_ = cfg

Custom HTTP Client

Implement gqlcli.Client to intercept or cache requests:

type CachedClient struct {
	inner gqlcli.Client
	cache map[string]map[string]interface{}
}

func (c *CachedClient) Execute(ctx context.Context, mode gqlcli.ExecutionMode, opts gqlcli.QueryOptions) (map[string]interface{}, error) {
	key := opts.Query
	if cached, ok := c.cache[key]; ok {
		return cached, nil
	}
	result, err := c.inner.Execute(ctx, mode, opts)
	if err == nil {
		c.cache[key] = result
	}
	return result, err
}

Registered Commands

builder.RegisterCommands(app) adds:

Command Description
query Execute a query
mutation Execute a mutation
batch Execute multiple operations (NDJSON/JSON array)
queries List Query fields
mutations List Mutation fields
types List schema types
describe Print SDL definition of a named type
config Manage .gqlcli.json environments
login Run a login mutation for an HTTP environment and save the token to .gqlcli.json
logout Clear the saved auth header for an HTTP environment
install-skill Install the gqlcli Claude Code skill into ~/.claude/skills/gqlcli/

Clone this wiki locally