Skip to content
Santekno.com | Tech Tutorials and Trends
EN
📖 0%
11 Sep 2025 · 6 min read ·Article 73 / 125
Go

73 Building an Auto-docs System in graphql-go

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

73 Building an Auto-docs System in graphql-go

As an organization grows, one thing that typically expands quickly (and often poorly) is API documentation. GraphQL offers an advantage with its built-in schema introspection, yet good documentation still needs to be enriched with business explanations and real-world examples. In this article, I want to walk you through building an auto-docs system —automated documentation— for a GraphQL API based on graphql-go. With this approach, we aim to reduce the gap between code and documentation: whatever changes in the code is automatically reflected in the docs.

Why Auto-Docs?

Auto-docs for GraphQL is nothing new. Platforms like Apollo, GraphQL Voyager, and GraphiQL already provide plenty of exploration tools. However, challenges arise when we:

  1. Want to embed the documentation in our internal style (our own developer portal).
  2. Need to add business details, remarks, or scenarios.
  3. Want to provide up-to-date documentation (not a copy-paste of last year’s schema).

If you use graphql-go , the introspection function is already available—but the result is still raw data that isn’t very informative for end-users or developers.

Auto-Docs System Architecture

Before implementation, let’s lay out a simple flow diagram below:

MERMAID
flowchart TD
    A[Source Code] --> B(GraphQL Schema & Resolvers)
    B --> C[Introspection Query]
    C --> D[Schema JSON]
    D --> E[Docs Generator]
    E --> F[Human-friendly HTML/Markdown Docs]

A simple explanation:

  • Source Code: you define the schema and resolvers in Go.
  • Introspection Query: the tool runs an introspection query against the *graphql.Schema.
  • Docs Generator: a builder script that reads the introspection result + custom annotations from your code.
  • Output: friendly documentation in HTML/Markdown that can be deployed.

Let’s break it down step by step.


Setting up the graphql-go Schema

Typically, you’d set up a schema like this:

go
 1import "github.com/graphql-go/graphql"
 2
 3var userType = graphql.NewObject(graphql.ObjectConfig{
 4    Name: "User",
 5    Fields: graphql.Fields{
 6        "id": &graphql.Field{
 7            Type: graphql.String,
 8            Description: "Unique identifier of the user",
 9        },
10        "name": &graphql.Field{
11            Type: graphql.String,
12            Description: "The user's full name",
13        },
14    },
15})
16
17var rootQuery = graphql.NewObject(graphql.ObjectConfig{
18    Name: "Query",
19    Fields: graphql.Fields {
20        "user": &graphql.Field{
21            Type: userType,
22            Description: "Find a user by ID",
23            Args: graphql.FieldConfigArgument{
24                "id": &graphql.ArgumentConfig{
25                    Type: graphql.NewNonNull(graphql.String),
26                },
27            },
28            Resolve: /* implement resolver... */
29        },
30    },
31})
32
33var schema, _ = graphql.NewSchema(graphql.SchemaConfig{
34    Query: rootQuery,
35})

Note: The Description on each type/field is key to making our documentation informative.


Running Introspection to Obtain the Schema

To build auto-docs, we first need introspection data.

Create a GraphQL endpoint that accepts the following introspection query:

graphql
 1query IntrospectionQuery {
 2    __schema {
 3        types {
 4            name
 5            description
 6            fields {
 7                name
 8                description
 9                args {
10                    name
11                    description
12                    type {
13                        name
14                        kind
15                    }
16                }
17                type {
18                    name
19                    kind
20                }
21            }
22        }
23    }
24}

For example, in Go:

go
1params := graphql.Params{
2    Schema: schema,
3    RequestString: introspectionQuery,
4}
5
6result := graphql.Do(params)
7resultJSON, _ := json.MarshalIndent(result, "", "  ")
8fmt.Println(string(resultJSON))

The output is JSON that you can consume for the next steps.


Building the Auto-Docs Generator

The next key part is the generator—a script that turns the introspection JSON into clean Markdown/HTML files. Here is a simple example in Go that converts the introspection output into Markdown:

go
 1package main
 2
 3import (
 4    "encoding/json"
 5    "io/ioutil"
 6    "os"
 7)
 8
 9type IntrospectionResult struct {
10    Data struct {
11        Schema struct {
12            Types []struct {
13                Name        string `json:"name"`
14                Description string `json:"description"`
15                Fields      []struct {
16                    Name        string `json:"name"`
17                    Description string `json:"description"`
18                } `json:"fields"`
19            } `json:"types"`
20        } `json:"__schema"`
21    } `json:"data"`
22}
23
24func main() {
25    // Read the introspection result file
26    data, _ := ioutil.ReadFile("schema.json")
27    var result IntrospectionResult
28    json.Unmarshal(data, &result)
29    
30    f, _ := os.Create("DOCS.md")
31    defer f.Close()
32
33    f.WriteString("# API Documentation\n")
34    for _, t := range result.Data.Schema.Types {
35        if t.Description != "" && len(t.Fields) > 0 {
36            f.WriteString("## " + t.Name + "\n" + t.Description + "\n")
37            for _, field := range t.Fields {
38                f.WriteString("- **" + field.Name + "**: " + field.Description + "\n")
39            }
40            f.WriteString("\n")
41        }
42    }
43}

The result is a Markdown document that auto-updates whenever the schema changes.


Adding Custom Annotations (Simulation)

You may want to add examples, formats, or other remarks. For this, our team typically uses a pattern of embedding custom tags into the Description:

go
 1var userType = graphql.NewObject(graphql.ObjectConfig{
 2    Name: "User",
 3    Fields: graphql.Fields{
 4        "email": &graphql.Field{
 5            Type: graphql.String,
 6            Description: `The user's main email.
 7@format: email
 8@example: user@example.com
 9@remark: Only verified emails shown.`,
10        },
11    },
12})

Then, in the docs generator, you can do a simple parse by splitting on @ to group that information. This lets you scale your documentation without having to change the schema structure.


Simulation Result and Documentation Table

Let’s simulate the docs output:

FieldDescriptionFormatExampleRemark
emailThe user’s main emailemailuser@example.comOnly verified emails shown.
nameThe user’s full name(none)(none)(none)

This is far more helpful for frontend developers or QA than reading raw introspection alone.


Auto-Docs CI/CD Pipeline

Best practice: this auto-docs process should be automated within a CI/CD pipeline.

MERMAID
graph TD
    CodeBase --> Build
    Build --> Execute_Introspection
    Execute_Introspection --> Generate_Docs
    Generate_Docs --> DeployDocs[Deploy to Docs Portal]
  1. Build: Build the code & schema.
  2. Execute_Introspection: Automate dumping the schema JSON.
  3. Generate_Docs: Run the generator to output HTML/Markdown.
  4. Deploy: Push to the documentation portal (could be GitHub Pages, S3, a web portal, etc.).

This way, the docs are always up-to-date, with no need for manual copy-pasting.


Conclusion: Auto-Docs, Simple but Powerful

The road to good API documentation isn’t complete with auto-docs alone. This approach does not replace manual documentation best practices, especially for business explanations, edge-case scenarios, and relationships between resources.

That said, from experience, an auto-docs system like this:

  • Cuts the lead time for updating docs when the schema changes,
  • Reduces confusion between teams,
  • Reduces bugs caused by documentation being out of sync with the implementation.

Integrating an auto-docs system is highly feasible with graphql-go without adding heavy dependencies. This framework can even serve as a foundation for a more advanced developer portal in the future.

Have experience or other auto-docs tips? Share them in the comments! 🚀

Related Articles

💬 Comments