remove pointers for optionality -- shockingly easy

This commit is contained in:
Ben Kraft
2021-03-22 17:37:44 -07:00
parent fed38e4f55
commit 463e3ed319
16 changed files with 39 additions and 38 deletions
+2 -1
View File
@@ -69,7 +69,7 @@ See [DESIGN.md](DESIGN.md) for documentation of major design decisions in this l
(+) denotes things we further need before recommending anyone else use this in prod
Generated code:
- (*) remove pointers for optionality (or put behind flag)
- add flag(s) to make a field use a pointer (for optionality or perf)
- redo support for interfaces, unions, fragments (see DESIGN)
- (optional) collapsing -- should be able to have `mutation { myMutation { error { code } } }` just return `(code string, err error)`
@@ -79,6 +79,7 @@ Config options:
- get schema via HTTP (perhaps even via GraphQL introspection)
- send hash rather than full query
- whether names should be exported
- default handling for optional fields (pointers, HasFoo, etc.)
Other:
- (*) error-checking/validation/etc. everywhere
+2 -2
View File
@@ -52,13 +52,13 @@ func Main() {
if err != nil {
return
}
fmt.Println("you are", *viewerResp.Viewer.MyName)
fmt.Println("you are", viewerResp.Viewer.MyName)
userResp, err := getUser(context.Background(), graphqlClient, username)
if err != nil {
return
}
fmt.Println(username, "is", *userResp.User.TheirName)
fmt.Println(username, "is", userResp.User.TheirName)
}
//go:generate go run github.com/Khan/genql genql.yaml
+3 -3
View File
@@ -9,11 +9,11 @@ import (
)
type GetUserResponse struct {
User *GetUserUser `json:"user"`
User GetUserUser `json:"user"`
}
type GetUserUser struct {
TheirName *string `json:"theirName"`
TheirName string `json:"theirName"`
}
type GetViewerResponse struct {
@@ -21,7 +21,7 @@ type GetViewerResponse struct {
}
type GetViewerViewerUser struct {
MyName *string
MyName string
}
func getViewer(ctx context.Context, client *graphql.Client) (*GetViewerResponse, error) {
+7 -7
View File
@@ -9,7 +9,7 @@ import (
)
type InputObjectQueryResponse struct {
User *InputObjectQueryUser `json:"user"`
User InputObjectQueryUser `json:"user"`
}
type InputObjectQueryUser struct {
@@ -17,11 +17,11 @@ type InputObjectQueryUser struct {
}
type UserQueryInput struct {
Email *string `json:"email"`
Name *string `json:"name"`
Id *string `json:"id"`
Role *UserQueryInputRole `json:"role"`
Names []*string `json:"names"`
Email string `json:"email"`
Name string `json:"name"`
Id string `json:"id"`
Role UserQueryInputRole `json:"role"`
Names []string `json:"names"`
}
type UserQueryInputRole string
@@ -31,7 +31,7 @@ const (
UserQueryInputRoleTeacher UserQueryInputRole = "TEACHER"
)
func InputObjectQuery(client *graphql.Client, query *UserQueryInput) (*InputObjectQueryResponse, error) {
func InputObjectQuery(client *graphql.Client, query UserQueryInput) (*InputObjectQueryResponse, error) {
variables := map[string]interface{}{
"query": query,
}
+2 -2
View File
@@ -9,14 +9,14 @@ import (
)
type ListInputQueryResponse struct {
User *ListInputQueryUser `json:"user"`
User ListInputQueryUser `json:"user"`
}
type ListInputQueryUser struct {
Id string `json:"id"`
}
func ListInputQuery(client *graphql.Client, names []*string) (*ListInputQueryResponse, error) {
func ListInputQuery(client *graphql.Client, names []string) (*ListInputQueryResponse, error) {
variables := map[string]interface{}{
"names": names,
}
+1 -1
View File
@@ -9,7 +9,7 @@ import (
)
type QueryWithAliasResponse struct {
User *QueryWithAliasUser
User QueryWithAliasUser
}
type QueryWithAliasUser struct {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
)
type QueryWithDoubleAliasResponse struct {
User *QueryWithDoubleAliasUser `json:"user"`
User QueryWithDoubleAliasUser `json:"user"`
}
type QueryWithDoubleAliasUser struct {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
)
type QueryWithEnumsResponse struct {
User *QueryWithEnumsUser `json:"user"`
User QueryWithEnumsUser `json:"user"`
}
type QueryWithEnumsUser struct {
+5 -5
View File
@@ -9,14 +9,14 @@ import (
)
type QueryWithSlicesResponse struct {
User *QueryWithSlicesUser `json:"user"`
User QueryWithSlicesUser `json:"user"`
}
type QueryWithSlicesUser struct {
Emails []string `json:"emails"`
EmailsOrNull []string `json:"emailsOrNull"`
EmailsWithNulls []*string `json:"emailsWithNulls"`
EmailsWithNullsOrNull []*string `json:"emailsWithNullsOrNull"`
Emails []string `json:"emails"`
EmailsOrNull []string `json:"emailsOrNull"`
EmailsWithNulls []string `json:"emailsWithNulls"`
EmailsWithNullsOrNull []string `json:"emailsWithNullsOrNull"`
}
func QueryWithSlices(client *graphql.Client) (*QueryWithSlicesResponse, error) {
+3 -3
View File
@@ -9,7 +9,7 @@ import (
)
type QueryWithStructsResponse struct {
User *QueryWithStructsUser `json:"user"`
User QueryWithStructsUser `json:"user"`
}
type QueryWithStructsUser struct {
@@ -17,8 +17,8 @@ type QueryWithStructsUser struct {
}
type QueryWithStructsUserAuthMethodsAuthMethod struct {
Provider *string `json:"provider"`
Email *string `json:"email"`
Provider string `json:"provider"`
Email string `json:"email"`
}
func QueryWithStructs(client *graphql.Client) (*QueryWithStructsResponse, error) {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
)
type SimpleInputQueryResponse struct {
User *SimpleInputQueryUser `json:"user"`
User SimpleInputQueryUser `json:"user"`
}
type SimpleInputQueryUser struct {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
)
type SimpleQueryResponse struct {
User *SimpleQueryUser `json:"user"`
User SimpleQueryUser `json:"user"`
}
type SimpleQueryUser struct {
+3 -3
View File
@@ -9,12 +9,12 @@ import (
)
type TypeNameQueryResponse struct {
User *TypeNameQueryUser `json:"user"`
User TypeNameQueryUser `json:"user"`
}
type TypeNameQueryUser struct {
Typename *string `json:"__typename"`
Id string `json:"id"`
Typename string `json:"__typename"`
Id string `json:"id"`
}
func TypeNameQuery(client *graphql.Client) (*TypeNameQueryResponse, error) {
+2 -2
View File
@@ -9,7 +9,7 @@ import (
)
type UnionNoFragmentsQueryRandomLeafArticle struct {
Typename *string `json:"__typename"`
Typename string `json:"__typename"`
}
func (v UnionNoFragmentsQueryRandomLeafArticle) implementsGraphQLInterfaceUnionNoFragmentsQueryRandomLeafLeafContent() {
@@ -20,7 +20,7 @@ type UnionNoFragmentsQueryRandomLeafLeafContent interface {
}
type UnionNoFragmentsQueryRandomLeafVideo struct {
Typename *string `json:"__typename"`
Typename string `json:"__typename"`
}
func (v UnionNoFragmentsQueryRandomLeafVideo) implementsGraphQLInterfaceUnionNoFragmentsQueryRandomLeafLeafContent() {
+2 -2
View File
@@ -31,8 +31,8 @@ const (
)
type UsesEnumTwiceQueryResponse struct {
Me *UsesEnumTwiceQueryMeUser
OtherUser *UsesEnumTwiceQueryOtherUser
Me UsesEnumTwiceQueryMeUser
OtherUser UsesEnumTwiceQueryOtherUser
}
func UsesEnumTwiceQuery(client *graphql.Client) (*UsesEnumTwiceQueryResponse, error) {
+3 -3
View File
@@ -225,9 +225,9 @@ func (builder *typeBuilder) writeType(namePrefix string, typ *ast.Type, fields [
builder.WriteString("[]")
typ = typ.Elem
}
if !typ.NonNull {
builder.WriteString("*")
}
// TODO: allow an option to make the Go type a pointer, if you want to do
// optionality that way, or perhaps others
// if !typ.NonNull { builder.WriteString("*") }
def := builder.schema.Types[typ.Name()]
// Writes a typedef elsewhere (if not already defined)