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

Ability to add our own directives #151

Open
renoirb opened this issue Jan 14, 2018 · 10 comments
Open

Ability to add our own directives #151

renoirb opened this issue Jan 14, 2018 · 10 comments

Comments

@renoirb
Copy link

renoirb commented Jan 14, 2018

May be related to #116.

CONTEXT

Author of this request is proficient JavaScript, but not in Go. Some statements in this issue may skewed perceptions based as a total beginner in Go.

REQUEST/QUESTION

Assuming we have a schema that supports Time scalar (like you've done in TestTime), and we want to use a custom formatter using GraphQL directives.

Is there plans for our own neelance/graphql-go GraphQL server implementation to create our own directives?

For example, we could get a n days ago, by defining our own @date(...) directive;

query {
  ago: addHour("2001-02-03T04:05:06Z") @date(as: "days ago")
}
// => { "ago": "6189 days ago" }

I'm aware not all types of Directives would be useful to ALL packages extending neelance/graphql-go.

It wouldn't make sense to have scalar Time exported by default.

But what I enjoyed in tests/, and the file time.go, was that I could see how I could implement my own scalar.

That would be awesome to have another example where one could see how to implement properly his own directive (e.g. @date).

OBSERVATIONS

As said in #116, it looks like the place we could append our own directives would be implemented are hidden away. I assume it's because lowerCased functions aren't exported in Go.

I see in internal/exec/selected/selected.go at line 194 how you’ve implemented @skip directive

And also how (black magic?) you’ve implemented @onQuery at internal/tests/testdata/tests.json {"schemas": []}, and ran from internal/tests/all_test.go TestAll

LINKS

Maybe you'd like to see some directives implemented in JavaScript, here is one implementation sample I found useful; lirown/graphql-custom-directives Date Formatting Directives

@renoirb
Copy link
Author

renoirb commented Jan 15, 2018

I've forked the project and started experimenting on how to make it happen

See renoirb/graphql-go, at branch issue-151

Desired outcome: Use field as type date, for example, as-is, but allow directive to tamper output.

Unless that's not a good idea.

Thoughts:

  • I'm aware that anything in the schema can be seen as a "directive" (type, enum, query, ... are "directives", right?)
  • Maybe FIELD directives could be attached or bound somehow
  • Maybe use ImplementsGraphQLType => "directive", how?

renoirb added a commit to renoirb/graphql-go that referenced this issue Jan 15, 2018
@tonyghita
Copy link
Member

Why use a directive rather than some input field in the arguments?

@renoirb
Copy link
Author

renoirb commented Jan 15, 2018

That can work, @tonyghita.

It would require making methods to return a String instead of an intended type. For example, we know lastModified is a date, but GraphQL will always return a string. But I would then have all fields I want with formatters to exist from two methods, the original and the formatted...able.

I was hoping I could find a way to create a type (e.g. like time.go does for new scalar) on which I could tell it's a Field Directive, where I could tell what return type it can format, and what options I can tell to use via enum.

I guess, at the moment, there is no way to attach to execution context (i.e. not at the same place we attach the schema, resolvers).

@renoirb
Copy link
Author

renoirb commented Jan 15, 2018

I'm curious tonsee if something is planned in that regard.

One thing I enjoy most about GraphQL is that we have something to really separate formatting logic from frontend.
Having each field, once per bounded context, to fulfill their types is great, It would be awesome we could have ways to pipe a formatter.

Maybe this project will allow this. That's why I'm asking.

@iamclaytonray
Copy link

I would think this functionality is best kept in the resolver, right? I can see the use-case of having custom directives but I would imagine this project abstracting over that a bit to allow you (the developer) to write your own custom directives & implementations without forcing the lib to take care of those custom directives & implementations.

@renoirb - What are your thoughts on that? I may not completely understand.

@renoirb
Copy link
Author

renoirb commented Jan 29, 2018

Hey @iamclaytonray, I haven't looked at this since my last comment.

You are right, in JavaScript Directives are attached at the resolver, at least the ones we want to use around the schema.

Here is a JavaScript module that allows this (implemented here).

I'm sure neelance is aware of how/where to implement this, and that's likely part of his plans. As I understand it (I can't find the reference for this, sorry) work has to be done to support directives because they can be used at many places in a schema (fragments, etc.) and there is no exposed functions, it is deep within "src/internals/".

I am currently designing a system, and had been analyzing the language we'll write our own GraphQL resolvers. We may pick this Go implementation of GraphQL, and we may be OK without Directives, my recommendation and the decision of my team aren't set in stone yet.

@namnm
Copy link

namnm commented Nov 10, 2018

Hi guys. Any news on this? Directives are useful in a lot of cases, looking forward to seeing the public API in this package!

@PepijnK
Copy link

PepijnK commented Dec 5, 2018

+1
Wanted to solve our role based backend calls with custom directives in the schema but found out the hard way that these are not supported? Can't think of another way without repeating a check inside each of the resolvers 😥. Guess with a directive based "middleware" (or interceptor) we could simply resolve the custom directive and block or pass the request.

@mistricky
Copy link

Any news here? I found the PR#370, is it related to this issue?

@abebars
Copy link

abebars commented Feb 19, 2021

is this something that can be supported I am looking for something similar like @hasScope(scope: ["test"]) that could be applied to Query & Mutation as well? @PepijnK did you find a workaround for that?

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

No branches or pull requests

7 participants