October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk6 min

Building a Directus API Client for Go

A practical guide to building a Go client for Directus, covering REST versus GraphQL, schema and permissions, authentication, transport design, and SDK evaluation.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

You can build a Directus client in Go with the standard net/http package or evaluate a community Go SDK. Start by choosing REST or GraphQL, then design around your Directus instance’s actual collections, fields, permissions, and authentication policy. Directus documents both API styles as exposing the same core functionality; the practical choice is usually which interface best fits your callers and codebase.

Choose REST, GraphQL, or a Go SDK

Directus generates its API endpoints and GraphQL schema from the connected database architecture, and what a user can access depends on the installation’s permissions. Directus says REST and GraphQL map to the same core services and expose the same functionality, so this is primarily an ergonomics decision—not a documented difference in capability. See the Directus API reference.

Option Consider it when Evaluate
REST You need conventional collection operations and want to avoid embedding GraphQL query strings. Whether its request and response shapes are convenient for your application.
GraphQL The caller benefits from expressing the requested data shape in a query. Query construction, response handling, and how queries fit your client’s interface.
Community Go SDK You prefer a library over implementing transport and API operations yourself. Compatibility with your Directus major version, endpoint coverage, maintenance, error behavior, authentication support, and dependency policy.
Custom Go client You want to keep dependencies small or tailor the interface to your application. The engineering cost of implementing and maintaining the operations you need.

Directus documents a composable TypeScript SDK, but the sources reviewed do not establish an official Directus-maintained Go SDK. The community project altipla-consulting/directus-go describes itself as a Go SDK and claims its v2 line targets Directus 11, while v0/v1 target Directus 10. Those are the project’s compatibility claims, not an independent assessment of its maintenance or completeness. Check the repository and test the operations your application relies on before adopting it.

Build a small REST transport first

A useful first step is a thin transport layer that centralizes the base URL, request context, HTTP client, bearer token, and response handling. Keep collection-specific methods separate so your application does not depend on a universal schema that Directus does not promise.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
package directus

import (
    "bytes"
    "context"
    "fmt"
    "io"
    "net/http"
    "strings"
    "time"
)

type Client struct {
    baseURL string
    token   string
    http    *http.Client
}

func New(baseURL, token string) (*Client, error) {
    baseURL = strings.TrimRight(baseURL, "/")
    if baseURL == "" {
        return nil, fmt.Errorf("directus base URL is required")
    }

    return &Client{
        baseURL: baseURL,
        token:   token,
        http:    &http.Client{Timeout: 15 * time.Second},
    }, nil
}

func (c *Client) do(ctx context.Context, method, path string, body []byte) ([]byte, error) {
    req, err := http.NewRequestWithContext(
        ctx,
        method,
        c.baseURL+"/"+strings.TrimLeft(path, "/"),
        bytes.NewReader(body),
    )
    if err != nil {
        return nil, fmt.Errorf("build Directus request: %w", err)
    }

    req.Header.Set("Accept", "application/json")
    if len(body) > 0 {
        req.Header.Set("Content-Type", "application/json")
    }
    if c.token != "" {
        req.Header.Set("Authorization", "Bearer "+c.token)
    }

    resp, err := c.http.Do(req)
    if err != nil {
        return nil, fmt.Errorf("send Directus request: %w", err)
    }
    defer resp.Body.Close()

    responseBody, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, fmt.Errorf("read Directus response: %w", err)
    }
    if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
        return nil, fmt.Errorf("Directus returned HTTP %s: %s", resp.Status, string(responseBody))
    }
    return responseBody, nil
}

The example uses a configurable base URL, a bounded HTTP timeout, a request context, bearer-header authentication when a token is configured, and response-body closure. It leaves error interpretation to callers: network/transport failures are wrapped separately from HTTP status failures. In production, consider whether response bodies can contain sensitive information before including them in errors or logs; redact them if needed. Add methods for the operations your application needs rather than turning this transport into a large collection of assumptions about Directus data.

Model the schema your instance actually exposes

Directus derives endpoints and the GraphQL schema from the connected database, while permissions affect available operations and returned data. A Go struct that assumes every Directus project has the same collections and fields is therefore unsafe as a general-purpose client design.

  • For an application tied to one project, define explicit Go types for the collections and fields that application owns or consumes.
  • For a reusable integration across unknown projects, provide generic decoding where appropriate, such as decoding JSON into map[string]any, or let callers supply their own types.
  • Handle absent or inaccessible fields as possible outcomes rather than assuming every user can read every field.
  • Keep project-specific collection names and request paths in configuration or application-level methods, not scattered through shared transport code.

Directus documents a server endpoint that returns the project’s OpenAPI specification. The specification is based on the current authenticated user’s read permissions, so it can help with schema inspection or code generation but should not be treated as a complete administrator-level inventory when retrieved with a less privileged account. See the Directus Server API reference.

Choose authentication for the integration

Directus states that “All data within the platform is private by default.” A project can configure a public role, or a client can authenticate to access private data. Directus documents temporary JWT access tokens returned by login, session tokens represented in cookies, and static user tokens. Temporary tokens are short-lived and paired with refresh tokens; static tokens do not expire and Directus describes them as less secure, though they can be useful for server-to-server communication. Details are in the Directus Authentication documentation.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Authentication choice Fit Important consideration
Public role Only for data and operations deliberately made public by the project configuration. Do not assume public access is enabled or appropriate for private data.
Static user token Potentially convenient for a server-to-server integration when deployment policy allows it. It does not expire and is described by Directus as less secure; protect and rotate it according to your organization’s policy.
Login and refresh Applications that need temporary-token and refresh behavior. Implement token lifecycle handling rather than treating an access token as permanent.
Cookie session Applications designed around Directus session cookies. Cross-domain cookie behavior depends on deployment configuration.

Make authentication an explicit client configuration choice. For token-based requests, send the token in the Authorization: Bearer … header, keep secrets out of source control, and avoid logging credentials. Directus specifically warns that the access_token query parameter is not recommended in production because systems may log query parameters; do not place bearer credentials in URLs.

Separate transport failures from API failures

A maintainable client should let callers distinguish a request that failed to reach the server from a response that arrived with an unsuccessful HTTP status. If you later parse Directus error payloads, preserve useful status and error details without exposing tokens or sensitive data in logs. The small example returns status text and response content in its HTTP error; adapt that policy to your application’s privacy and observability requirements. The reviewed Directus sources do not prescribe a Go error type, so choose one that fits your callers and document what it retains.

  • Use request contexts so callers can cancel work or set deadlines.
  • Set a client timeout appropriate to the application, and allow it to be configured if operations have different latency needs.
  • Close every response body, including responses with unsuccessful status codes.
  • Keep response decoding and Directus-specific error parsing in a layer above raw HTTP transport.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Validate against the target project

Before relying on a client in production, test it against the Directus version, schema, and user permissions it will actually encounter. In particular, verify that its authentication flow works for the deployment, that expected collections and fields are visible to the chosen account, and that its error handling remains useful when a request is denied or otherwise unsuccessful. If you use generated models, retrieve the OpenAPI specification with an account whose permissions match the intended client; the result is permission-sensitive.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.