graphqlclientgen

package module
v0.16.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 29, 2025 License: MIT Imports: 6 Imported by: 1

README

graphqlclientgen

Here Be Dragons 🐉

This is an experiment of generating GraphQL clients in Golang. It's heavily inspired by gqlgen.

  • Goals
    • Structure config and generated clients in a future proof way to enable redesign of codegen
    • Single client generated for entire schema
    • ProtoClient interface to support multiple protocols and custom clients
    • Use static types in client interface to check api compability during build time
    • Enable field selection in client to partially fetch objects
  • Limitations
    • No support for arguments on fields (yet)

Get started

  1. Add graphqlclientgen to tools.go
    //go:build tools
    
    package tools
    
    import (
      _ "github.com/loa/graphqlclientgen/cmd"
    )
    
  2. Run go tidy to add graphqlclientgen as dependency
    go mod tidy
    
  3. Create a new directory and run graphqlclientgen init
    mkdir exampleclient
    cd exampleclient
    
    go run github.com/loa/graphqlclientgen/cmd init --schema-path='../graph/*.graphqls'
    
  4. Run generate (init creates exampleclient.go with go gen comment)
    go generate .
    

Examples

func Example() {
  // create client, supports custom protocols through ProtoClient interface
  c := client.New(graphqlclientgen.NewHttpClient("http://localhost:8080/query"))

  todo, err := c.CreateTodo(context.TODO(),
    // static typed inputs
    client.NewTodo{
      Text:   "bar",
      UserId: "5",
    },
    // explicit requested fields, easy to use with auto-complete
    client.TodoFields{
      client.TodoFieldID,
      client.TodoFieldText,
      // supports requesting specific fields of related objects
      client.TodoFieldUser{
        client.UserFieldID,
        client.UserFieldName,
      },
    })

  if err != nil {
    var gerr graphqlclientgen.Error
    if errors.As(err, &gerr) {
      // match errors by extension
      if gerr.ExtensionEqualString("code", "NOT_FOUND") {
        // handle user not found
      } else if gerr.ExtensionEqualString("code", "INVALID_INPUT") {
        // handle invalid text input
      }
    }
  }
}

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrExtensionNotFound = errors.New("extension not found")
)

Functions

This section is empty.

Types

type Body

type Body struct {
	Query     string         `json:"query"`
	Variables map[string]any `json:"variables"`
}

type Error

type Error []ErrorEntry

https://spec.graphql.org/draft/#sec-Errors

Example
err := Error{
	{
		Message: "entry with incorrect type",
		Extensions: map[string]json.RawMessage{
			"featureA": json.RawMessage(`"true"`),
		},
	},
	{
		Message: "entry with correct type",
		Extensions: map[string]json.RawMessage{
			"featureA": json.RawMessage("true"),
		},
	},
}

fmt.Println(err.Error())
Output:

entry with incorrect type
entry with correct type

func (Error) Error added in v0.15.0

func (err Error) Error() string

func (Error) ExtensionBool added in v0.15.0

func (err Error) ExtensionBool(key string) (bool, bool)

func (Error) ExtensionEqualBool added in v0.15.0

func (err Error) ExtensionEqualBool(key string, value bool) bool

func (Error) ExtensionEqualInt added in v0.15.0

func (err Error) ExtensionEqualInt(key string, value int) bool

func (Error) ExtensionEqualString added in v0.15.0

func (err Error) ExtensionEqualString(key, value string) bool

func (Error) ExtensionFloat64 added in v0.15.0

func (err Error) ExtensionFloat64(key string) (float64, bool)

func (Error) ExtensionInt added in v0.15.0

func (err Error) ExtensionInt(key string) (int, bool)

func (Error) ExtensionString added in v0.15.0

func (err Error) ExtensionString(key string) (string, bool)

func (Error) ExtensionUnmarshal added in v0.15.0

func (err Error) ExtensionUnmarshal(key string, in any) error

func (Error) Unwrap added in v0.15.0

func (err Error) Unwrap() []error

type ErrorEntry added in v0.15.0

type ErrorEntry struct {
	Message    string                     `json:"message"`
	Path       []string                   `json:"path"`
	Locations  []Location                 `json:"locations"`
	Extensions map[string]json.RawMessage `json:"extensions"`
}

func (ErrorEntry) Error added in v0.15.0

func (entry ErrorEntry) Error() string

func (ErrorEntry) ExtensionBool added in v0.15.0

func (entry ErrorEntry) ExtensionBool(key string) (bool, bool)

func (ErrorEntry) ExtensionFloat64 added in v0.15.0

func (entry ErrorEntry) ExtensionFloat64(key string) (float64, bool)

func (ErrorEntry) ExtensionInt added in v0.15.0

func (entry ErrorEntry) ExtensionInt(key string) (int, bool)

func (ErrorEntry) ExtensionString added in v0.15.0

func (entry ErrorEntry) ExtensionString(key string) (string, bool)

func (ErrorEntry) ExtensionUnmarshal added in v0.15.0

func (entry ErrorEntry) ExtensionUnmarshal(key string, in any) error

type HttpClient

type HttpClient struct {
	// contains filtered or unexported fields
}

func NewHttpClient

func NewHttpClient(url string, opts ...HttpClientOpts) HttpClient

NewHttpClient creates a new HttpClient for graphqlclientgen clients

func (HttpClient) Do

func (httpClient HttpClient) Do(ctx context.Context, in Body, out any) error

Do performs http post request towards a GraphQL api

type HttpClientOpts

type HttpClientOpts func(*HttpClient)

func WithHttpClient

func WithHttpClient(c *http.Client) HttpClientOpts

WithHttpClient sets a custom http.Client for HttpClient

type Location added in v0.15.0

type Location struct {
	Line   int `json:"line"`
	Column int `json:"column"`
}

type ProtoClient

type ProtoClient interface {
	Do(ctx context.Context, in Body, out any) error
}

type Response

type Response struct {
	Data   json.RawMessage `json:"data"`
	Errors *Error          `json:"errors"`
}

Directories

Path Synopsis
tests

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL