-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Do not include unhelpful scalar types. #9
Comments
There's a really good way analogy I can think of that shows how silly it is to have these types. Imagine if the package json
// Boolean represents JSON booleans.
type Boolean bool
// Float represents JSON numbers.
type Float float64
// String represents JSON strings.
type String string And suggested that users did this: var jsonBlob = []byte(`[
{"Name": "Platypus", "Order": "Monotremata"},
{"Name": "Quoll", "Order": "Dasyuromorphia"}
]`)
type Animal struct {
Name json.String
Order json.String
}
var animals []Animal
err := json.Unmarshal(jsonBlob, &animals)
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%+v", animals) |
That said, we don't want to remove all scalar types. Only those that are easily replaceable by built in Go types. For example, we'll remove But we'll keep |
I tried implementing this, and quickly found out that removing the primitive scalar types isn't viable. There are two directions to consider when it comes to interacting with a GraphQL API. One is sending data from your program (i.e., inputs, variables), and the other is receiving the results (query response). When dealing with the response, we can consider making use of However, when it comes to sending data to GraphQL API, the only types it supports are those primitives that are defined. GraphQL will only accept an I'll keep this open and keep thinking/experimenting with what can be done to improve the user experience on the receiving response side. But all scalars will stay, because they're needed when sending input. |
This serves as further motivation for #9.
Not sure this is the best place for this, but is there a way to convert the githubql.String to native string? |
@gcrevell You can use a conversion, e.g.: var s1 githubql.String
var s2 string
s2 = string(s1) // type conversion If var query struct {
Viewer struct {
Login string
}
} (You only really need to use I want to update the README to make this information more accessible. |
I've started using predeclared Go types in many of my queries since a while ago, and it makes the user experience much better. Document this possibility so that other people can benefit from it too. Updates #9.
In hopes of helping anyone else who might run into this: I had a query that looked like: // PullRequestHeadBranch gets the head branch and node ID of a given pull request.
func (c *V4Client) PullRequestHeadBranch(ctx context.Context, repo Repo, prNumber int) (branchName, nodeID string, err error) {
var q struct {
Repository struct {
PullRequest struct {
ID string
HeadRefName string
} `graphql:"pullRequest(number: $prNumber)"`
} `graphql:"repository(owner: $owner, name: $name)"`
}
vars := map[string]interface{}{
"owner": repo.Owner, // <-- Problem! Don't use a plain string.
"name": repo.Name,// <-- Problem! Don't use a plain string.
"prNumber": prNumber, // <-- Problem! Don't use a plain int.
}
if err := c.Client.Query(ctx, &q, vars); err != nil {
return "", "", err
}
pr := q.Repository.PullRequest
return pr.HeadRefName, pr.ID, nil
} And I was getting an error Changing the lines with the |
@dmitshur how can I set a query-variable to null? If I have a map[string]interface and set "somekey": nil it fails at writeArgumentType. I have a pagingElement which should be null on 1st page. |
@davidkarlsen Something like this should work: variables := map[string]interface{}{
"somekey": (*githubv4.String)(nil), // or another concrete type instead of String
// ...
} |
Thanks - I found info in another issue too - it works fine now. |
Is it possible to pass an array for an argument, like in the GraphQL example here? https://gist.github.com/alexellis/6212c988189323dbb2806d1c7f7699ab |
This is an issue with the current API design I've come to feel by using the API more, by thinking about it more, and through some user feedback (/cc @slimsag).
Right now,
githubql
defines a custom type for each GitHub GraphQL API scalar:https://developer.github.com/v4/reference/scalar/
https://github.com/shurcooL/githubql/blob/bd2ca14c68143d6449401ed5c65ddefe7ef9058f/scalar.go#L19-L61
Some of them are very primitive types that the Go type system already offers as built in types:
I created
scalar.go
completely by hand (it's so small, and unlikely to change often, that auto-generating it from schema wasn't worth it at this time). The thinking was thatgithubql
should expose all types in the GitHub GraphQL schema, and scalars were a small and easy place to start. So I added all of them. Which lets you write code like this:Some early user feedback immediately pointed it out as a source of uncertainty/unexpected complexity:
And the answer is those custom types are absolutely not needed. In fact, I had a note at the top of
schalar.go
:After writing more and more code that uses
githubql
, I've come to realize these types are simply counter-productive. Using them adds no value to the code, only makes it more verbose by forcing you to do type conversions. Not using them feels weird because they exist, and README demonstrates them being used.Compare, using them:
Vs using Go's equivalent built in types:
Additionally, sometimes you query for an int:
And immediately try to convert it to
uint64
, for example:But instead, you might as well ask for a
uint64
to be decoded into in the query:This should not be more unsafe. As long as a query is executed successfully at least once, it'll always work. Besides, someone could've accidentally used
githubql.String
wheregithubql.Int
should've been used, the compiler wouldn't catch that either.The only useful purpose they serve is documentation of GitHub GraphQL scalars, but I think we need to provide such documentation without actually having the unneeded types.
The text was updated successfully, but these errors were encountered: