Comments (10)
Hi @kmulvey
Maybe you could share how far you've gotten into the go version, we could help you better that way :)
In the meantime, this is how I would do:
- First I'd define the schema using GraphQL Schema Language (shameless plug: cheat sheet here )
type RootQuery {
post: Post
}
type Post {
_id: String!
title: String
content: String
author: Author
}
type Author {
_id: String!
name: String
}
- Next, here's is a rough equivalent of the JS version that you posted.
Note that I've left out the business / app logic to retrieve/find posts/author etc.
Hope this helps you move into the right direction, let me know if you need further help.
Cheers!
package main
import (
"github.com/graphql-go/graphql"
"fmt"
)
// Define GraphQL Schema
var AuthorObject = graphql.NewObject(graphql.ObjectConfig{
Name: "Author",
Description: "This respresents an Author",
Fields: graphql.Fields{
"_id": &graphql.Field{
Type: graphql.NewNonNull(graphql.String),
},
"name": &graphql.Field{
Type: graphql.String,
},
},
})
var PostObject = graphql.NewObject(graphql.ObjectConfig{
Name: "Post",
Description: "This respresents an Post",
Fields: graphql.Fields{
"_id": &graphql.Field{
Type: graphql.NewNonNull(graphql.String),
},
"title": &graphql.Field{
Type: graphql.NewNonNull(graphql.String),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
// get title from source
title, _ := p.Source["title"].(string)
if title == "" {
// return error
return nil, fmt.Errorf("Does not exists")
}
return title, nil
},
},
"content": &graphql.Field{
Type: graphql.String,
},
"author": &graphql.Field{
Type: AuthorObject,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
// get title from source
title, _ := p.Source["title"].(string)
// add business logic to retrieve find for given post title
return author, nil
},
},
},
})
var RootQuery = graphql.NewObject(graphql.ObjectConfig{
Name: "BlogSchema",
Description: "Root of the Blog Schema",
Fields: graphql.Fields{
"posts": &graphql.Field{
Type: graphql.NewList(PostObject),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
// add business logic to retrieve list of Posts
return PostsList
},
},
"echo": &graphql.Field{
Type: graphql.String,
Description: "Echo what you enter",
Args: graphql.FieldConfigArgument{
"message": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
// get arg value
message, _ := p.Args["message"].(string)
return message, nil
},
},
},
})
from graphql.
query posts {
posts {
title
author {
name
}
}
user {
name
posts {
title
}
}
}
I'm not sure your question is related to the issue you posted in. Nor am I sure exactly what you're asking.
from graphql.
@artshpakov Ah, okay. So basically, in the case of types that have to reference other types and the requirement for the type to be non-null in GraphQL you'd delay field definition.
Define your Post type without Authors, and define your Authors type without posts, then once the two exist without reference each other use Object.AddFieldConfig to tie them together (add a posts to Author and add a author to Post).
from graphql.
thanks @sogko for the quick reply. I was able to advance your example a bit and get the correct structure out but now the values are coming out null. I have a feeling I made a silly mistake somewhere but can't seem to spot it. Also authorObject (commented out) won't compile if i leave the "posts" section in. Thanks for your help.
https://gist.github.com/kmulvey/4843061d16492a24ce2663e497dda528
{
"data": {
"posts": [
{
"author": {
"name": null
},
"title": null
},
{
"author": {
"name": null
},
"title": null
},
etc ...
]
}
}
from graphql.
hi @kmulvey
Actually you almost had it.
Since you are returning Golang structs in Resolve() functions, you need to let graphql-go
know how to map the struct fields to your GraphQL fields.
Currently we use json
tags for this.
(This is shown in the examples, but unfortunately we have not done a good job with the documentation to highlight this)
Simply update your struct implementations with the json
tags, mapping it to the field names defined in your schema. (Note the capitalisation)
// User respresents an author
type User struct {
ID int `json:"_id"`
Age int `json:"age"`
Name string `json:"name"`
Posts []Post `json:"posts"`
}
// Post is a blog post
type Post struct {
ID int `json:"_id"`
UserID int `gorm:"index"` // json-tag not needed since you are not using this field currently
Title string `gorm:"type:varchar(100);unique_index" json:"title"`
}
{
"data": {
"posts": [
{
"author": {
"name": "userOne"
},
"title": "post one"
},
{
"author": {
"name": "userOne"
},
"title": "post two"
},
{
"author": {
"name": "userTwo"
},
"title": "post three"
},
{
"author": {
"name": "userTwo"
},
"title": "post four"
}
]
}
}
If I find the time, I can do a complete implementation of the example gist you gave earlier, to compare notes.
Cheers!
from graphql.
What if I need to perform both
{posts {title,author {name}}}
and
{user {name,posts {title}}}
queries?
from graphql.
@bbuck
Sorry if I misunderstood some graphql concepts in general, but I was referring to the golang code snippet above. It shows how to implement your Post and User types in case you want to query posts with authors embedded. So you've got to have your AuthorObject to be defined when you define PostObject. What I'm asking about is the case when you need both posts with nesting author
posts{title text author{name}}
and authors with nested posts author(id:1){name posts{title text}}
. You cannot have a "posts" field on AuthorObject because you have no PostObject defined yet.
Like, in Ruby graphql gem you can have that with
PostType = GraphQL::ObjectType.define do
field :title, !types.String
field :text, !types.String
field :author, types[UserType] do
resolve -> (obj, args, ctx) { User.find(obj.user_id) }
end
end
UserType = GraphQL::ObjectType.define do
field :name, !types.String
field :posts, types[PostType] do
resolve -> (obj, args, ctx) { obj.posts }
end
end
QueryType = GraphQL::ObjectType.define do
field :posts, types[PostType] do
resolve ->(obj, args, ctx) { Post.all }
end
field :user do
type UserType
argument :id, !types.ID
resolve -> (obj, args, ctx) { User.find(args["id"]) }
end
end
What I'm asking is if there's any way to do the same with graphql-go.
from graphql.
@bbuck I see. That will quickly become clumsy though -- at least when your APIs start to grow and you decide to have your type definitions in separate files.
from graphql.
We use it in production and don't see any issues with it. I'm not sure how it can become clumsy.
from graphql.
Sorry to revive an old thread - I can open a new issue but it's related to this comment: #129 (comment).
In the example, the RootQuery has a posts
field that has a Resolve
that fetches all the posts and returns them.
My understanding is that then the PostObject
resolvers start trying to figure out the _id
, title
, content
and author
. The author
resolver uses p.Source
to determine which author to look up and return.
I have a local example of something very similar, but for the author
resolve function, p.Source
is []Posts
where I expected it to be a single Post
and just have graphql-go call my resolver once for each Post
the initial resolver received.
Is this a graphql thing?
How am I supposed to use p.Source
to determine a particular author
if I'm getting an array back?
from graphql.
Related Issues (20)
- Is using graphql base on RPC instead of HTTP expectable?
- Cannot parse GitHub public schema v4
- Create graphql schema from string HOT 3
- 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
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.