...

Text file src/github.com/cli/shurcooL-graphql/README.md

Documentation: github.com/cli/shurcooL-graphql

     1graphql
     2=======
     3
     4Package `graphql` provides a GraphQL client implementation, and is forked from `https://github.com/shurcooL/graphql`.
     5
     6Installation
     7------------
     8
     9```bash
    10go get -u github.com/cli/shurcooL-graphql
    11```
    12
    13Usage
    14-----
    15
    16Construct a GraphQL client, specifying the GraphQL server URL. Then, you can use it to make GraphQL queries and mutations.
    17
    18```Go
    19client := graphql.NewClient("https://example.com/graphql", nil)
    20// Use client...
    21```
    22
    23### Authentication
    24
    25Some 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`](https://golang.org/x/oauth2) package. You'll need an OAuth token with the right scopes. Then:
    26
    27```Go
    28import "golang.org/x/oauth2"
    29
    30func main() {
    31	src := oauth2.StaticTokenSource(
    32		&oauth2.Token{AccessToken: os.Getenv("GRAPHQL_TOKEN")},
    33	)
    34	httpClient := oauth2.NewClient(context.Background(), src)
    35
    36	client := graphql.NewClient("https://example.com/graphql", httpClient)
    37	// Use client...
    38```
    39
    40### Simple Query
    41
    42To make a GraphQL query, you need to define a corresponding Go type.
    43
    44For example, to make the following GraphQL query:
    45
    46```GraphQL
    47query {
    48	me {
    49		name
    50	}
    51}
    52```
    53
    54You can define this variable:
    55
    56```Go
    57var query struct {
    58	Me struct {
    59		Name graphql.String
    60	}
    61}
    62```
    63
    64Then call `client.Query`, passing a pointer to it:
    65
    66```Go
    67err := client.Query(context.Background(), &query, nil)
    68if err != nil {
    69	// Handle error.
    70}
    71fmt.Println(query.Me.Name)
    72
    73// Output: Luke Skywalker
    74```
    75
    76### Arguments and Variables
    77
    78Often, you'll want to specify arguments on some fields. You can use the `graphql` struct field tag for this.
    79
    80For example, to make the following GraphQL query:
    81
    82```GraphQL
    83{
    84	human(id: "1000") {
    85		name
    86		height(unit: METER)
    87	}
    88}
    89```
    90
    91You can define this variable:
    92
    93```Go
    94var q struct {
    95	Human struct {
    96		Name   graphql.String
    97		Height graphql.Float `graphql:"height(unit: METER)"`
    98	} `graphql:"human(id: \"1000\")"`
    99}
   100```
   101
   102Then call `client.Query`:
   103
   104```Go
   105err := client.Query(context.Background(), &q, nil)
   106if err != nil {
   107	// Handle error.
   108}
   109fmt.Println(q.Human.Name)
   110fmt.Println(q.Human.Height)
   111
   112// Output:
   113// Luke Skywalker
   114// 1.72
   115```
   116
   117However, 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:
   118
   119```Go
   120var q struct {
   121	Human struct {
   122		Name   graphql.String
   123		Height graphql.Float `graphql:"height(unit: $unit)"`
   124	} `graphql:"human(id: $id)"`
   125}
   126```
   127
   128Then, define a `variables` map with their values:
   129
   130```Go
   131variables := map[string]any{
   132	"id":   graphql.ID(id),
   133	"unit": starwars.LengthUnit("METER"),
   134}
   135```
   136
   137Finally, call `client.Query` providing `variables`:
   138
   139```Go
   140err := client.Query(context.Background(), &q, variables)
   141if err != nil {
   142	// Handle error.
   143}
   144```
   145
   146### Inline Fragments
   147
   148Some GraphQL queries contain inline fragments. You can use the `graphql` struct field tag to express them.
   149
   150For example, to make the following GraphQL query:
   151
   152```GraphQL
   153{
   154	hero(episode: "JEDI") {
   155		name
   156		... on Droid {
   157			primaryFunction
   158		}
   159		... on Human {
   160			height
   161		}
   162	}
   163}
   164```
   165
   166You can define this variable:
   167
   168```Go
   169var q struct {
   170	Hero struct {
   171		Name  graphql.String
   172		Droid struct {
   173			PrimaryFunction graphql.String
   174		} `graphql:"... on Droid"`
   175		Human struct {
   176			Height graphql.Float
   177		} `graphql:"... on Human"`
   178	} `graphql:"hero(episode: \"JEDI\")"`
   179}
   180```
   181
   182Alternatively, you can define the struct types corresponding to inline fragments, and use them as embedded fields in your query:
   183
   184```Go
   185type (
   186	DroidFragment struct {
   187		PrimaryFunction graphql.String
   188	}
   189	HumanFragment struct {
   190		Height graphql.Float
   191	}
   192)
   193
   194var q struct {
   195	Hero struct {
   196		Name          graphql.String
   197		DroidFragment `graphql:"... on Droid"`
   198		HumanFragment `graphql:"... on Human"`
   199	} `graphql:"hero(episode: \"JEDI\")"`
   200}
   201```
   202
   203Then call `client.Query`:
   204
   205```Go
   206err := client.Query(context.Background(), &q, nil)
   207if err != nil {
   208	// Handle error.
   209}
   210fmt.Println(q.Hero.Name)
   211fmt.Println(q.Hero.PrimaryFunction)
   212fmt.Println(q.Hero.Height)
   213
   214// Output:
   215// R2-D2
   216// Astromech
   217// 0
   218```
   219
   220### Mutations
   221
   222Mutations often require information that you can only find out by performing a query first. Let's suppose you've already done that.
   223
   224For example, to make the following GraphQL mutation:
   225
   226```GraphQL
   227mutation($ep: Episode!, $review: ReviewInput!) {
   228	createReview(episode: $ep, review: $review) {
   229		stars
   230		commentary
   231	}
   232}
   233variables {
   234	"ep": "JEDI",
   235	"review": {
   236		"stars": 5,
   237		"commentary": "This is a great movie!"
   238	}
   239}
   240```
   241
   242You can define:
   243
   244```Go
   245var m struct {
   246	CreateReview struct {
   247		Stars      graphql.Int
   248		Commentary graphql.String
   249	} `graphql:"createReview(episode: $ep, review: $review)"`
   250}
   251variables := map[string]any{
   252	"ep": starwars.Episode("JEDI"),
   253	"review": starwars.ReviewInput{
   254		Stars:      graphql.Int(5),
   255		Commentary: graphql.String("This is a great movie!"),
   256	},
   257}
   258```
   259
   260Then call `client.Mutate`:
   261
   262```Go
   263err := client.Mutate(context.Background(), &m, variables)
   264if err != nil {
   265	// Handle error.
   266}
   267fmt.Printf("Created a %v star review: %v\n", m.CreateReview.Stars, m.CreateReview.Commentary)
   268
   269// Output:
   270// Created a 5 star review: This is a great movie!
   271```
   272
   273License
   274-------
   275
   276-	[MIT License](LICENSE)

View as plain text