Comments (15)
Woah the improvements starting to look good 👍🏻
My humble notes:
1. Resolve function
graphql.ResolveParams
is a great improvement overgraphql.GQLFRParams
👍🏻- There is a proposal in issue #28 to allow user functions to return
error
instead of forcing them to panic.
If any,executor
will then return nil and add the user-returned error into thegraphql.Result
helloResolve := func(p graphql.ResolveParams) (interface{}, error) {
return "world", nil
}
2. graphql.Fields, graphql.Field
This is definitely a much need improvement (i.e. renaming FieldConfigMap
and FieldConfig
.
In the proposed example, it is a []graphql.Fields{}
slice.
How about we retain it as map? Because the field key and the field name can be different.
(The name
config is used in the introspection query and for documentation)
package graphql
type Field struct
type Fields map[string]*Field
...
package example
fields := graphql.Fields{
"hello": &graphql.Field{Name: "Hello Field", Type: graphql.String, Resolve: helloResolve},
}
3. graphql.NewSchema() and root query
At first glance, the new NewSchema()
method looks cleaner. But it might be veering too much from graphql
. The proposed example looks like it can only define a root object for query operation (ie. RootQuery). We still need a way to define mutation root query.
A GraphQL schema is represented by a root type for each kind of operation: query and mutation; this determines the place in the type system where those operations begin.
Source: http://facebook.github.io/graphql/#sec-Type-System
func main() {
helloResolve := func(p graphql.ResolveParams) interface{} {
return "world"
}
queryFields := graphql.Fields{
"hello": graphql.Field{Name: "Hello Field", Type: graphql.String, Resolve: helloResolve},
}
rootQuery := graphql.NewObject(graphql.ObjectConfig{
Name: "RootQuery",
Fields: queryFields,
})
schema, err := graphql.NewSchema(graphql.SchemaConfig{Query: rootQuery})
// or with mutation,
// schema, err := graphql.NewSchema(graphql.SchemaConfig{Query: rootQuery, Mutation: mutationQuery})
if err != nil {
log.Fatalf("failed to create new schema, error: %v", err)
}
...
}
4. Constructor configs
I wish we can get rid of the config structs for the constructor. There is some hope; there is a proposal for named arguments to be added to the language golang/go#12296 and golang/go#12854, but realistically, it would take awhile.
5. graphql.Do()
I'm in favour of this over the current go graphql.Graphql(...)
👍🏻
Your example shows go graphql.Do(schema, query, result)
; are you suggesting we replace the graphql.Params
?
Cheers!
from graphql.
I think that
result := make(chan *graphql.Result)
go graphql.Do(schema, query, result)
r := <-result
is a very complicated interface. As far as I can tell, there's no need for the result channel at all (everything in the executor appears to be synchronous), but if it is required then it'd be nice for graphql.Do
to handle creating the channel and waiting for the result. In other words,
r := graphql.Do(schema, query)
would be my ideal interface.
from graphql.
I also prefer the Do syntax.
Even the Fields slice seems easier for typing those long types.
from graphql.
Update: @Fugiman submitted PR #48 to improve the graphql.Graphql(...)
Updateupdate: Merged 👍🏻
from graphql.
Definitely looking forward to more robust error handling and less panic()
at the disco :)
from graphql.
Hi @sogko I would like to get support on custom error reporting as #74
I can think of two approaches
- change
Resolve
function signature to indicate errror as well
helloResolve := func(p graphql.ResolveParams) (interface{}, error) {
return "world", nil
}
This is explained by @sogko above
2. Check returned value is an error interface in executor
http://play.golang.org/p/xoPSMAbEAB
package main
import "fmt"
func Resolve(isErr bool) interface{} {
if isErr {
return fmt.Errorf("got an error")
}
return 2 + 1
}
func assert(res interface{}) {
if err, ok := res.(error); ok {
fmt.Println(err.Error())
} else {
fmt.Printf("got value %d", res)
}
}
func main() {
assert(Resolve(true))
assert(Resolve(false))
}
//returns
got an error
got value 3
tradeoff
Option 1 has the benefit of being explicit and idiomatic in go sense. At the same time need API change.
Option 2 has the benefit of no API change but retuned result has some implicit meaning.
I prefer option 1 and being explicit. I can work on this if you all agree.
Cheers,
bsr
from graphql.
@chris-ramon @sogko any comment on error handling. currently the framework is catching panic and suppressing the cause of error. I keep hitting this as Iost context information make it hard to track down an error. Please give some priority on this.
from graphql.
Right now what I do is comment out the defers and recovers in executor.go that really helps and crashes your server a lot. But then that is only for development. We are actually planning to make a graphql implementation using code generation for performance in the future.
from graphql.
@pyros2097 with code generation? tell us more :)
from graphql.
By we I mean my company. Well we have 3 Type systems one was our postgres types, then go types and then graphql types. So to map go types to postgres types and tables we had done it using code generation using go generate. But didn't have time to do it for graphql types also. So say you have a struct
type User struct {
ID string `json:"id"`
name string `json:"id"`
}
we had to manually create a graphql type for each struct and that was a bit painful as we already know what types ID and name were and even needed to create custom scalar types for validation like PLPassword(which I think should be done in Go and on the struct). So you techincally wouldn't need to create all graphql types, maybe you might only need to resolve the fields.
And another thing we found out was that a lot of reflection was used for serialization and de-serialization and the current graphql implementation we need to resolve interfaces or map[string]interfaces{} which can be improved if you know the type you need to json encode.
We are planning to have some thing that can do something like a rails orm does for you but with also graphql types ex: sql -> structs -> graphql objects.
And by the way we have recently finished 2 projects and are currently testing it out.
Awesome work @sogko and @chris-ramon thanks to you guys we didn't need write an rpc layer between go and nodejs 👍
@atrniv Any word on the implementation you were talking about? (PS He is the code generation guy you can look at all his projects they all have code generation in them even the js ones )
from graphql.
@pyros2097 thanks for the tip. that helps :-)
from graphql.
Thanks for sharing your thoughts and concerns about api/lib design/improvement guys! 🌟
I've started working on extending graphql.FieldResolveFn
to return error as second parameter: (interface{}, error)
, as @bsr203 mentioned above, work under progress on: #80
from graphql.
@chris-ramon you rock :-) I can see the effort you putting in this. tx.
Can you also look at #65 with this as you may be touching the same functions :-) Even if we don't use context, just being consistent is enough now map[string]interface{} -> interface{}
from graphql.
@pkieltyka We have implemented it and using it on our live servers you can check the tests out although there is no documentation whatsoever ... https://github.com/playlyfe/go-graphql
from graphql.
Let's close this one; and have a new conversation on API improvements on new issues, thanks a lot for bringing great ideas guys 👍 🌟
from graphql.
Related Issues (20)
- The code generator does not take into account naming conflicts HOT 1
- How to take metro in graphql out of the solve?
- Is this project still mantained? HOT 2
- New release?
- Potential goroutine leak in TestContextDeadline HOT 1
- Enums with trailing white space cause error.
- Playground
- make union input type ? it just have output union type
- With fiber HOT 1
- Printing GraphQL documents is slow HOT 1
- Bug with underscore and same name in keys from json response
- MongoDB _id field
- Printer returns invalid SDL if Block String comment contains double-quote
- When using custom scalar types, it's crucial to provide error feedback to users when issues arise with their submitted data. However, triggering exceptions within the ParseValue and ParseLiteral methods can lead to program crashes when using the graphql.Do method. This prevents the necessary error messages from being delivered to users.
- String type no longer recongised HOT 1
- Is it possible to go from `*graphql.Schema` to an ast node? HOT 1
- Error handling HOT 1
- Disabling Field Suggestions
- Is possible to typing typeConfig of graphql.Object after Object done.
- RootObjectFn request body always empty
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphql.