graphql

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2023 License: MIT Imports: 12 Imported by: 1

README

graphql

Package graphql provides a GraphQL client implementation.

Installation

graphql requires Go version 1.19 or later.

go get -u github.com/vinhluan/go-graphql-client

Usage

Construct a GraphQL client, specifying the GraphQL server URL. Then, you can use it to make GraphQL queries and mutations.

client := graphql.NewClient("https://example.com/graphql", nil)
// Use client...
Authentication

Some GraphQL servers may require authentication. The graphql package does not directly handle authentication. Instead, when creating a new client, you're expected to pass an http.Client that performs authentication. The easiest and recommended way to do this is to use the golang.org/x/oauth2 package. You'll need an OAuth token with the right scopes. Then:

import "golang.org/x/oauth2"

func main() {
    src := oauth2.StaticTokenSource(
        &oauth2.Token{AccessToken: os.Getenv("GRAPHQL_TOKEN")},
    )
    httpClient := oauth2.NewClient(context.Background(), src)

    client := graphql.NewClient("https://example.com/graphql", httpClient)
    // Use client...
Simple Query

To make a GraphQL query, you need to define a corresponding Go type.

For example, to make the following GraphQL query:

query {
    me {
        name
    }
}

You can define this variable:

var query struct {
    Me struct {
        Name graphql.String
    }
}

Then call client. Query , passing a pointer to it:

err := client.Query(context.Background(), &query, nil)
if err != nil {
    // Handle error.
}
fmt.Println(query.Me.Name)

// Output: Luke Skywalker
Arguments and Variables

Often, you'll want to specify arguments on some fields. You can use the graphql struct field tag for this.

For example, to make the following GraphQL query:

{
    human(id: "1000") {
        name
        height(unit: METER)
    }
}

You can define this variable:

var q struct {
    Human struct {
        Name   graphql.String
        Height graphql.Float `graphql:"height(unit: METER)"`
    } `graphql:"human(id: \"1000\")"`
}

Then call client.Query :

result, err := client.Query(context.Background(), &q, nil)
if err != nil {
    // Handle error.
}
fmt.Println(q.Human.Name)
fmt.Println(q.Human.Height)

// Output:
// Luke Skywalker
// 1.72

However, that'll only work if the arguments are constant and known in advance. Otherwise, you will need to make use of variables. Replace the constants in the struct field tag with variable names:

var q struct {
    Human struct {
        Name   graphql.String
        Height graphql.Float `graphql:"height(unit: $unit)"`
    } `graphql:"human(id: $id)"`
}

Then, define a variables map with their values:

variables := map[string]interface{}{
    "id":   graphql.ID(id),
    "unit": starwars.LengthUnit("METER"),
}

Finally, call client.Query providing variables :

result, err := client.Query(context.Background(), &q, variables)
if err != nil {
    // Handle error.
}
Inline Fragments

Some GraphQL queries contain inline fragments. You can use the graphql struct field tag to express them.

For example, to make the following GraphQL query:

{
    hero(episode: "JEDI") {
        name
        ... on Droid {
            primaryFunction
        }
        ... on Human {
            height
        }
    }
}

You can define this variable:

var q struct {
    Hero struct {
        Name  graphql.String
        Droid struct {
            PrimaryFunction graphql.String
        } `graphql:"... on Droid"`
        Human struct {
            Height graphql.Float
        } `graphql:"... on Human"`
    } `graphql:"hero(episode: \"JEDI\")"`
}

Alternatively, you can define the struct types corresponding to inline fragments, and use them as embedded fields in your query:

type (
    DroidFragment struct {
        PrimaryFunction graphql.String
    }
    HumanFragment struct {
        Height graphql.Float
    }
)

var q struct {
    Hero struct {
        Name          graphql.String
        DroidFragment `graphql:"... on Droid"`
        HumanFragment `graphql:"... on Human"`
    } `graphql:"hero(episode: \"JEDI\")"`
}

Then call client. Query :

result, err := client.Query(context.Background(), &q, nil)
if err != nil {
    // Handle error.
}
fmt.Println(q.Hero.Name)
fmt.Println(q.Hero.PrimaryFunction)
fmt.Println(q.Hero.Height)

// Output:
// R2-D2
// Astromech
// 0
Mutations

Mutations often require information that you can only find out by performing a query first. Let's suppose you've already done that.

For example, to make the following GraphQL mutation:

mutation($ep: Episode!, $review: ReviewInput!) {
    createReview(episode: $ep, review: $review) {
        stars
        commentary
    }
}
variables {
    "ep": "JEDI",
    "review": {
        "stars": 5,
        "commentary": "This is a great movie!"
    }
}

You can define:

var m struct {
    CreateReview struct {
        Stars      graphql.Int
        Commentary graphql.String
    } `graphql:"createReview(episode: $ep, review: $review)"`
}
variables := map[string]interface{}{
    "ep": starwars.Episode("JEDI"),
    "review": starwars.ReviewInput{
        Stars:      graphql.Int(5),
        Commentary: graphql.String("This is a great movie!"),
    },
}

Then call client. Mutate :

result, err := client.Mutate(context.Background(), &m, variables)
if err != nil {
    // Handle error.
}
fmt.Printf("Created a %v star review: %v\n", m.CreateReview.Stars, m.CreateReview.Commentary)

// Output:
// Created a 5 star review: This is a great movie!

Directories

Path Synopsis
example/graphqldev graphqldev is a test program currently being used for developing graphql package.
ident Package ident provides functions for parsing and converting identifier names between various naming convention.
internal/jsonutil Package jsonutil provides a function for decoding JSON into a GraphQL query data structure.

Documentation

Overview

Package graphql provides a GraphQL client implementation.

For more information, see package github.com/shurcooL/githubv4, which is a specialized version targeting GitHub GraphQL API v4. That package is driving the feature development.

For now, see README for more details.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Boolean

type Boolean bool

Boolean represents true or false values.

func NewBoolean

func NewBoolean(v Boolean) *Boolean

NewBoolean is a helper to make a new *Boolean.

type Client

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

Client is a GraphQL client.

func NewClient

func NewClient(url string, httpClient *http.Client) *Client

NewClient creates a GraphQL client targeting the specified GraphQL server URL. If httpClient is nil, then http.DefaultClient is used.

func (*Client) Mutate

func (c *Client) Mutate(ctx context.Context, m interface{}, variables map[string]interface{}) (*Result, error)

Mutate executes a single GraphQL mutation request, with a mutation derived from m, populating the response into it. m should be a pointer to struct that corresponds to the GraphQL schema.

func (*Client) MutateString

func (c *Client) MutateString(ctx context.Context, m string, variables map[string]interface{}, v interface{}) (*Result, error)

MutateString executes a single GraphQL mutation request, using the given raw query `m` and populating the response into it. `m` should be a correct GraphQL mutation request string that corresponds to the GraphQL schema.

func (*Client) Query

func (c *Client) Query(ctx context.Context, q interface{}, variables map[string]interface{}) (*Result, error)

Query executes a single GraphQL query request, with a query derived from q, populating the response into it. q should be a pointer to struct that corresponds to the GraphQL schema.

func (*Client) QueryString

func (c *Client) QueryString(ctx context.Context, q string, variables map[string]interface{}, v interface{}) (*Result, error)

QueryString executes a single GraphQL query request, using the given raw query `q` and populating the response into the `v`. `q` should be a correct GraphQL query request string that corresponds to the GraphQL schema.

type Float

type Float float64

Float represents signed double-precision fractional values as specified by IEEE 754.

func NewFloat

func NewFloat(v Float) *Float

NewFloat is a helper to make a new *Float.

type GraphQL

type GraphQL interface {
	QueryString(ctx context.Context, q string, variables map[string]interface{}, v interface{}) (*Result, error)
	Query(ctx context.Context, q interface{}, variables map[string]interface{}) (*Result, error)

	Mutate(ctx context.Context, m interface{}, variables map[string]interface{}) (*Result, error)
	MutateString(ctx context.Context, m string, variables map[string]interface{}, v interface{}) (*Result, error)
}

type ID

type ID interface{}

ID represents a unique identifier that is Base64 obfuscated. It is often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as "VXNlci0xMA==") or integer (such as 4) input value will be accepted as an ID.

func NewID

func NewID(v ID) *ID

NewID is a helper to make a new *ID.

type Int

type Int int32

Int represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.

func NewInt

func NewInt(v Int) *Int

NewInt is a helper to make a new *Int.

type OpErrors

type OpErrors []struct {
	Message   string
	Locations []struct {
		Line   int
		Column int
	}
}

OpErrors represents the "errors" array in a response from a GraphQL server. If returned via error interface, the slice is expected to contain at least 1 element.

Specification: https://facebook.github.io/graphql/#sec-Errors.

func (OpErrors) Error

func (e OpErrors) Error() string

Error implements error interface.

type Result

type Result struct {
	Data       *json.RawMessage
	Errors     OpErrors
	Extensions map[string]interface{}
}

type String

type String string

String represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.

func NewString

func NewString(v String) *String

NewString is a helper to make a new *String.

Directories

Path Synopsis
example
graphqldev
graphqldev is a test program currently being used for developing graphql package.
graphqldev is a test program currently being used for developing graphql package.
Package ident provides functions for parsing and converting identifier names between various naming convention.
Package ident provides functions for parsing and converting identifier names between various naming convention.
internal
jsonutil
Package jsonutil provides a function for decoding JSON into a GraphQL query data structure.
Package jsonutil provides a function for decoding JSON into a GraphQL query data structure.
Package mock is a generated GoMock package.
Package mock is a generated GoMock package.

Jump to

Keyboard shortcuts

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