Skip to content
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

Separate resolvers for queries and mutations #182

Closed
wants to merge 7 commits into from

Conversation

sanae10001
Copy link
Contributor

See #145

@sanae10001
Copy link
Contributor Author

github.com/graph-gophers/graphql-go (download)
github.com/opentracing/opentracing-go (download)
Fetching https://golang.org/x/net/context?go-get=1
Parsing meta tags from https://golang.org/x/net/context?go-get=1 (status code 200)
get "golang.org/x/net/context": found meta tag main.metaImport{Prefix:"golang.org/x/net", VCS:"git", RepoRoot:"https://go.googlesource.com/net"} at https://golang.org/x/net/context?go-get=1
get "golang.org/x/net/context": verifying non-authoritative meta tag
Fetching https://golang.org/x/net?go-get=1
Parsing meta tags from https://golang.org/x/net?go-get=1 (status code 200)
golang.org/x/net (download)
graphql.go:10:2: use of internal package not allowed
graphql.go:11:2: use of internal package not allowed
graphql.go:12:2: use of internal package not allowed
graphql.go:13:2: use of internal package not allowed
graphql.go:14:2: use of internal package not allowed
graphql.go:15:2: use of internal package not allowed
graphql.go:16:2: use of internal package not allowed
internal/exec/exec.go:11:2: use of internal package not allowed
internal/exec/exec.go:12:2: use of internal package not allowed
internal/exec/exec.go:13:2: use of internal package not allowed
internal/exec/exec.go:14:2: use of internal package not allowed
internal/exec/exec.go:15:2: use of internal package not allowed
internal/exec/packer/packer.go:10:2: use of internal package not allowed
internal/exec/packer/packer.go:11:2: use of internal package not allowed
internal/exec/resolvable/meta.go:7:2: use of internal package not allowed
internal/exec/resolvable/resolvable.go:12:2: use of internal package not allowed
internal/exec/resolvable/meta.go:8:2: use of internal package not allowed
internal/exec/selected/selected.go:9:2: use of internal package not allowed
internal/exec/selected/selected.go:10:2: use of internal package not allowed
internal/exec/selected/selected.go:11:2: use of internal package not allowed
internal/exec/selected/selected.go:12:2: use of internal package not allowed
internal/exec/selected/selected.go:13:2: use of internal package not allowed
internal/query/query.go:9:2: use of internal package not allowed
internal/schema/schema.go:9:2: use of internal package not allowed
internal/validation/validation.go:12:2: use of internal package not allowed
internal/validation/validation.go:13:2: use of internal package not allowed
internal/validation/validation.go:14:2: use of internal package not allowed
introspection/introspection.go:6:2: use of internal package not allowed
introspection/introspection.go:7:2: use of internal package not allowed

What happened?

@ghostiam
Copy link

This change will break compatibility and many people will have to rewrite their code.
I don't want a repeat of the story > satori/go.uuid#66

@tonyghita
Copy link
Member

@sanae10001 are you still working within $GOPATH/src/github.com/neelance/graphql-go? You probably want to update your working directory.

@GhostRussia there may be some way that we can provide the new functionality without breaking clients (i.e. via some option or some temporary cleverness in the resolver lookup code).

Either way, we'll want to ensure we communicate the changes and impact of the changes before merging this in.

@ghostiam
Copy link

ghostiam commented Mar 15, 2018

I think can use the interface to determine the type of resolver.

type Queryer interface {
	Query() interface{}
}

type Mutationer interface {
	Mutation() interface{}
}

And when using interfaces, we do not have to do extra reflection.

rFunc := root.MethodByName("Query")
if !rFunc.IsValid() {
	return nil, errors.New("not found query resolver")
}
 
queryResolver = rFunc.Call(nil)[0]

use:

type RootResolver struct {
}

func (r *Resolver) Query() interface{} {
	return &QueryResolver{}
}

func (r *Resolver) Mutation() interface{} {
	return &MutationResolver{}
}

graphql.MustParseSchema(schema, &RootResolver),

I checked here, this code allows working with two versions of resolvers. Original tests pass, but other tests are needed.

full resolvers patch:
https://gist.github.com/GhostRussia/faa89c113cfca55366ee3867193d4d09#file-0001-separate-resolver-patch

Adapted tests patch:
https://gist.github.com/GhostRussia/faa89c113cfca55366ee3867193d4d09#file-0002-separate-resolver-test-patch

and pass test https://github.com/graph-gophers/graphql-go/pull/182/files#diff-3a3269459d813f994deb0997a653aac2
after change

- func (r *RootResolver) Query() *QueryResolver {
+ func (r *RootResolver) Query() interface{} {
	return &QueryResolver{}
}

- func (r *RootResolver) Mutation() *MutationResolver {
+ func (r *RootResolver) Mutation() interface{} {
	return &MutationResolver{}
}

@ghostiam
Copy link

ghostiam commented Mar 16, 2018

#182 (comment)
@tonyghita SemaphoreCI still working within $GOPATH/src/github.com/neelance/graphql-go for PR

@tonyghita
Copy link
Member

Looks like we had two webhooks to the SemaphoreCI integration that were racing each other. I removed the old one that pointed to the previous repository, so we shouldn't see these issues.

@mytototo
Copy link

Hi there,

Is there any ETA regarding this PR?
How do you want to handle backward compatibilities?

Thanks a lot for your contribution.

@sanae10001
Copy link
Contributor Author

sanae10001 commented Apr 10, 2018

@mytototo Now, it don't break compatibility. All above codes can correctly run. Maybe more tests are needed.

@mytototo
Copy link

@sanae10001 Ok, thanks a lot.

@cad
Copy link

cad commented Sep 24, 2018

Any plan on merging this?

@mrg0lden
Copy link

mrg0lden commented Nov 5, 2018

Do you need any help with this PR to get it merged? @pavelnikolov

@pavelnikolov
Copy link
Member

I'm trying to respond promptly to all new issues and PRs. I'm sorry for the delay on existing PRs. I'll review shortly.

@pavelnikolov
Copy link
Member

I wonder if this can be done in a way that doesn't introduce a breaking change 🤔

@sanae10001
Copy link
Contributor Author

sanae10001 commented Nov 16, 2018

I wonder if this can be done in a way that doesn't introduce a breaking change 🤔

It don't break compatibility. All above codes can correctly run.

@mrg0lden
Copy link

mrg0lden commented Nov 16, 2018 via email

@pavelnikolov
Copy link
Member

I wonder if this can be done in a way that doesn't introduce a breaking change 🤔

It don't break compatibility. All above codes can correctly run.

This is not completely true. You had to change the Star Wars example, right? This means that all users of the library will have to do the same when they switch to the latest version. It's not optional. It forces the users to upgrade.

@pavelnikolov
Copy link
Member

BTW, what about implementing Go modules? This way we can introduce breaking changes with time when a gain is found.

Maybe it's a good idea. This in turn, would also increase complexity. I don't want to introduce something without a clear problem that it solves. This is a very dangerous path that can lead to a lot of unnecessary complexity with very little ROI.

@sanae10001
Copy link
Contributor Author

@pavelnikolov
Sorry, my mistake.
The changes of Star Wars example only are legacy codes on commit 80ff5e1.
Already restore.

@johnmaguire
Copy link

@pavelnikolov I'm wondering what the state of this ticket is. As @sanae10001 mentioned, the PR has code to determine if the resolvers are separated or not, and falls back on the existing behavior.

@pavelnikolov
Copy link
Member

@johnmaguire it is not currently being worked on, as far as I know.

@maoueh
Copy link

maoueh commented Oct 21, 2021

See #421 for a workaround for that, we use this PR in production code, all our resolver's name are prefixed with either Query, Mutation or Subscription.

@johnmaguire
Copy link

Excuse my ignorance @pavelnikolov but my impression was that this PR was ready for review but has since generated merge conflicts. Is there a reason it wasn't merged in 2018? Would it be merged if it were cleaned up today?

It's worth noting that the gqlgen feature comparsion page points to this issue as a point of distinction for their project.

@pavelnikolov
Copy link
Member

@sanae10001 I started working on this and will try to add it to the next release. I like your code and I will copy some portion of it.

@pavelnikolov
Copy link
Member

Closing this in favor of #561

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants