start of wiring for configurable context
This commit is contained in:
@@ -273,6 +273,8 @@ Additionally, users may want to get the client from the context, using a custom
|
||||
|
||||
This can all be configurable globally -- say you can decide whether to use context and client, and optionally provide the type of your context and/or a function that gets client from it, or something. We'll want to pick a good default before we have external users, so as not to break them, but it's easy enough to change the Khan-specific parts via codemod later.
|
||||
|
||||
**Decision:** It seems easy enough to allow all of this to be configured: you can specify no context, a specific context type, or the default of context.Context; and then if you want you can specify a way to get the client from context or a global. We'll need both hooks at Khan, and it's not much harder to add them in a generalizable way.
|
||||
|
||||
### Query extraction (for safelisting)
|
||||
|
||||
One thing we want to be able to do is to make it clear exactly what query-document (down to comments and whitespace) we will be sending in the query for the purposes of safelisting and querying based on hash. In the case where you have one query per file, that's easy, just use the whole file. But you may want to share fragments between queries, in which case this is trouble: you either need a way to include fragments from another file (and a defined concatenation order), or you need to have several queries per file, and either have genql extract the right parts (in a defined/reproducible way), or have it send up the full file and the operation name to use (in which case we should still encourage you to not do that unless you're hashing, so that you aren't sending up too much data). We could also allow configuration between the last two options (so if you don't care about hashing/safelisting you can auto-extract).
|
||||
|
||||
+27
-7
@@ -5,15 +5,16 @@ import (
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
var defaultConfig = &Config{
|
||||
Schema: "schema.graphql",
|
||||
Queries: "queries.graphql",
|
||||
Generated: "generated.go",
|
||||
UseContext: true,
|
||||
Schema: "schema.graphql",
|
||||
Queries: "queries.graphql",
|
||||
Generated: "generated.go",
|
||||
ContextType: "context.Context",
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
@@ -30,9 +31,19 @@ type Config struct {
|
||||
// The filename to which to write the generated code; defaults to
|
||||
// generated.go
|
||||
Generated string `yaml:"generated"`
|
||||
// Whether the generated helpers should accept a context.Context which will
|
||||
// be used to make the request; defaults to true.
|
||||
UseContext bool `yaml:"use_context"`
|
||||
// Set to the fully-qualified name of a type which generated helpers should
|
||||
// accept and use as the context.Context for HTTP requests. Defaults to
|
||||
// context.Context; set to the empty string to omit context entirely.
|
||||
ContextType string `yaml:"context_type"`
|
||||
// TODO: implement client-getters
|
||||
// If set, a snippet of Go code to get a *graphql.Client from the context
|
||||
// (which will be named ctx). For example, this might do
|
||||
// ctx.Value(myKey).(*graphql.Client). If omitted, client must be
|
||||
// passed to each method explicitly.
|
||||
// TODO: what if you want to do an import in this snippet, e.g. for a
|
||||
// getter function, global var, or a context-key-type?
|
||||
// TODO: what if you want to return err?
|
||||
// ClientGetter string `yaml:"client_getter"`
|
||||
}
|
||||
|
||||
func (c *Config) ValidateAndFillDefaults() error {
|
||||
@@ -53,6 +64,15 @@ func (c *Config) ValidateAndFillDefaults() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) ContextPackage() string {
|
||||
if c.ContextType == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
i := strings.LastIndex(c.ContextType, ".")
|
||||
return c.ContextType[:i]
|
||||
}
|
||||
|
||||
func ReadAndValidateConfig(filename string) (*Config, error) {
|
||||
config := *defaultConfig
|
||||
if filename != "" {
|
||||
|
||||
@@ -3,7 +3,9 @@ package {{.Config.Package}}
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
{{- if .Config.ContextType -}}
|
||||
"{{.Config.ContextPackage}}"
|
||||
{{end}}
|
||||
{{- if .ImportJSON -}}
|
||||
"encoding/json"
|
||||
{{end}}
|
||||
@@ -11,11 +13,13 @@ import (
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
{{/* TODO: type-assert that your ctx type implements context.Context */}}
|
||||
|
||||
{{.Types}}
|
||||
|
||||
{{range .Operations}}
|
||||
{{.Doc}}
|
||||
func {{.Name}}({{if $.Config.UseContext}}ctx context.Context, {{end}}client *graphql.Client{{range .Args}}, {{.GoName}} {{.GoType}}{{end}}) (*{{.ResponseName}}, error) {
|
||||
func {{.Name}}({{if $.Config.ContextType}}ctx {{$.Config.ContextType}}, {{end}}client *graphql.Client{{range .Args}}, {{.GoName}} {{.GoType}}{{end}}) (*{{.ResponseName}}, error) {
|
||||
{{- if .Args -}}
|
||||
variables := map[string]interface{}{
|
||||
{{range .Args -}}
|
||||
@@ -24,7 +28,7 @@ func {{.Name}}({{if $.Config.UseContext}}ctx context.Context, {{end}}client *gra
|
||||
}
|
||||
{{end}}
|
||||
var retval {{.ResponseName}}
|
||||
err := client.MakeRequest({{if $.Config.UseContext}}ctx{{else}}context.Background(){{end}}, `{{.Body}}`, &retval, {{if .Args}}variables{{else}}nil{{end}})
|
||||
err := client.MakeRequest({{if $.Config.ContextType}}ctx{{else}}nil{{end}}, `{{.Body}}`, &retval, {{if .Args}}variables{{else}}nil{{end}})
|
||||
return &retval, err
|
||||
}
|
||||
{{end}}
|
||||
|
||||
+1
-3
@@ -3,8 +3,6 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
@@ -37,7 +35,7 @@ func InputObjectQuery(client *graphql.Client, query UserQueryInput) (*InputObjec
|
||||
}
|
||||
|
||||
var retval InputObjectQueryResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query InputObjectQuery ($query: UserQueryInput) {
|
||||
user(query: $query) {
|
||||
id
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
@@ -95,7 +95,7 @@ func (v InterfaceNoFragmentsQueryRootTopicChildrenVideo) implementsGraphQLInterf
|
||||
|
||||
func InterfaceNoFragmentsQuery(client *graphql.Client) (*InterfaceNoFragmentsQueryResponse, error) {
|
||||
var retval InterfaceNoFragmentsQueryResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query InterfaceNoFragmentsQuery {
|
||||
root {
|
||||
id
|
||||
|
||||
+1
-3
@@ -3,8 +3,6 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
@@ -22,7 +20,7 @@ func ListInputQuery(client *graphql.Client, names []string) (*ListInputQueryResp
|
||||
}
|
||||
|
||||
var retval ListInputQueryResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query ListInputQuery ($names: [String]) {
|
||||
user(query: {names:$names}) {
|
||||
id
|
||||
|
||||
+1
-3
@@ -3,8 +3,6 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
@@ -18,7 +16,7 @@ type QueryWithAliasUser struct {
|
||||
|
||||
func QueryWithAlias(client *graphql.Client) (*QueryWithAliasResponse, error) {
|
||||
var retval QueryWithAliasResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query QueryWithAlias {
|
||||
User: user {
|
||||
ID: id
|
||||
|
||||
+1
-3
@@ -3,8 +3,6 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
@@ -19,7 +17,7 @@ type QueryWithDoubleAliasUser struct {
|
||||
|
||||
func QueryWithDoubleAlias(client *graphql.Client) (*QueryWithDoubleAliasResponse, error) {
|
||||
var retval QueryWithDoubleAliasResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query QueryWithDoubleAlias {
|
||||
user {
|
||||
ID: id
|
||||
|
||||
+1
-3
@@ -3,8 +3,6 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
@@ -25,7 +23,7 @@ const (
|
||||
|
||||
func QueryWithEnums(client *graphql.Client) (*QueryWithEnumsResponse, error) {
|
||||
var retval QueryWithEnumsResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query QueryWithEnums {
|
||||
user {
|
||||
roles
|
||||
|
||||
+1
-3
@@ -3,8 +3,6 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
@@ -21,7 +19,7 @@ type QueryWithSlicesUser struct {
|
||||
|
||||
func QueryWithSlices(client *graphql.Client) (*QueryWithSlicesResponse, error) {
|
||||
var retval QueryWithSlicesResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query QueryWithSlices {
|
||||
user {
|
||||
emails
|
||||
|
||||
+1
-3
@@ -3,8 +3,6 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
@@ -23,7 +21,7 @@ type QueryWithStructsUserAuthMethodsAuthMethod struct {
|
||||
|
||||
func QueryWithStructs(client *graphql.Client) (*QueryWithStructsResponse, error) {
|
||||
var retval QueryWithStructsResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query QueryWithStructs {
|
||||
user {
|
||||
authMethods {
|
||||
|
||||
+1
-3
@@ -3,8 +3,6 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
@@ -22,7 +20,7 @@ func SimpleInputQuery(client *graphql.Client, name string) (*SimpleInputQueryRes
|
||||
}
|
||||
|
||||
var retval SimpleInputQueryResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query SimpleInputQuery ($name: String!) {
|
||||
user(query: {name:$name}) {
|
||||
id
|
||||
|
||||
+1
-3
@@ -3,8 +3,6 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
@@ -18,7 +16,7 @@ type SimpleQueryUser struct {
|
||||
|
||||
func SimpleQuery(client *graphql.Client) (*SimpleQueryResponse, error) {
|
||||
var retval SimpleQueryResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query SimpleQuery {
|
||||
user {
|
||||
id
|
||||
|
||||
+1
-3
@@ -3,8 +3,6 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
@@ -19,7 +17,7 @@ type TypeNameQueryUser struct {
|
||||
|
||||
func TypeNameQuery(client *graphql.Client) (*TypeNameQueryResponse, error) {
|
||||
var retval TypeNameQueryResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query TypeNameQuery {
|
||||
user {
|
||||
__typename
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
@@ -73,7 +73,7 @@ func (v *UnionNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
func UnionNoFragmentsQuery(client *graphql.Client) (*UnionNoFragmentsQueryResponse, error) {
|
||||
var retval UnionNoFragmentsQueryResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query UnionNoFragmentsQuery {
|
||||
randomLeaf {
|
||||
__typename
|
||||
|
||||
+1
-3
@@ -3,8 +3,6 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
@@ -37,7 +35,7 @@ type UsesEnumTwiceQueryResponse struct {
|
||||
|
||||
func UsesEnumTwiceQuery(client *graphql.Client) (*UsesEnumTwiceQueryResponse, error) {
|
||||
var retval UsesEnumTwiceQueryResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query UsesEnumTwiceQuery {
|
||||
Me: user {
|
||||
roles
|
||||
|
||||
+1
-3
@@ -3,8 +3,6 @@ package test
|
||||
// Code generated by github.com/Khan/genql, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Khan/genql/graphql"
|
||||
)
|
||||
|
||||
@@ -37,7 +35,7 @@ func unexported(client *graphql.Client, query userQueryInput) (*unexportedRespon
|
||||
}
|
||||
|
||||
var retval unexportedResponse
|
||||
err := client.MakeRequest(context.Background(), `
|
||||
err := client.MakeRequest(nil, `
|
||||
query unexported ($query: UserQueryInput) {
|
||||
user(query: $query) {
|
||||
id
|
||||
|
||||
@@ -47,6 +47,7 @@ func (builder *typeBuilder) maybeWriteUnmarshal(fields []field) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
builder.ImportJSON = true
|
||||
builder.WriteString("\n\n")
|
||||
return unmarshalTemplate.Execute(builder, data)
|
||||
}
|
||||
|
||||
+3
-1
@@ -50,7 +50,9 @@ func (client *Client) MakeRequest(ctx context.Context, query string, retval inte
|
||||
return err
|
||||
}
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
if ctx != nil {
|
||||
req = req.WithContext(ctx)
|
||||
}
|
||||
resp, err := client.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user