Currently functions is a top-level field in graphcool.yml containing a handler and a type + extra configuration depending on the type.
We will remove the top level functions field and instead introduce three specific fields:
containing the handler and configuration appropriate for the specific type.
The reasoning for this is that we want to introduce handlers that are not functions as described in #585
In addition we will introduce the top-level handlers field which can be used to define named handlers:
handlers:
send-welcome-email:
code:
src: ./code/sendEmail.js
subscriptions:
user-signed-up:
subscription: ./subscriptions/userSignedUp.graphql
handler: send-welcome-mail
This is especially useful for #543 that will reference a named handler from the types.graphql file as below
handlers:
facebook-authentication:
code:
src: ./code/facebook-authentication.js
type FacebookUser @model {
id: ID! @isUnique
facebookUserId: String @isUnique
facebookEmail: String
createdAt: DateTime!
updatedAt: DateTime!
}
type AuthenticateFacebookUserPayload {
token: String!
}
extend type Mutation {
authenticateFacebookUser(facebookToken: String!) @resolver(handler: "facebook-authentication"): AuthenticateFacebookUserPayload
}
I'm not entirely convinced about the naming of the top-level handlers field. The alternative is to call it functions, but I like to clearly indicate that this is describing a handler.
Would love to get some input. cc @schickling
Resolvers? That might change the attribute to @resolver(name: '...') instead of @resolver(resolver: '...') though...
@kbrandwijk If they are used only for actual GraphQL resolvers, I think that would be appropriate.
My current thinking is that they should also work as named handlers that can be referenced from a subscription for example.
Do you think calling them resolvers would work in that case?
Do you think we should rather say that they can only be used as actual GraphQL resolvers?
@sorenbs I can't really visualize what you're saying about referencing handlers from a subscription. I think you should stay as close as possible to the GraphQL principles, so resolvers fit right into that.
Also, with regards to subscriptions, if you would use a function as implementation for a subscription (if that's what you meant), than that's still called a resolver (for example: http://dev.apollodata.com/tools/graphql-subscriptions/subscriptions-to-schema.html#subscription-server)
I ment a serverside subscription like in the example above:
handlers:
send-welcome-email:
code:
src: ./code/sendEmail.js
subscriptions:
user-signed-up:
subscription: ./subscriptions/userSignedUp.graphql
handler: send-welcome-mail
What I am trying to understand is whether we should keep the handler terminology or we should simply call it resolver in all places.
@marktani @nikolasburk @timsuchanek I would love some input on this :-)
@sorenbs Thank you for clarifying that. I think resolver is still closest to what it actually is in GraphQL terminology, both for 'former SE'-resolvers as for 'former SSS'-resolvers.
To me, it would be like this:
I don't see how a handler for server side subscriptions or hooks would fit the resolver terminology. That's why I like the top-level term handler better, because it's more generic. Resolvers referenced in types.graphql would use @resolver(handler: "send-welcome-email").
Thanks for the input!
We have decided to stick with handlers and the
@resolver(handler: "facebook-authentication")
syntax for resolvers in types.graphql
We have decided to backtrack on this :-)
Introducing multiple top-level fields for different kind of functions makes it difficult to group functions in a big graphcool.yml file. It's possible to achieve grouping by using modules, but we feel that having one graphcool.yml file will be so common that we need to optimise for this case.
resolver functions will be referenced like this:
functions:
facebook-auth:
handler:
code:
src: ./code/facebook-authentication.js
type: resolver
type FacebookUser @model {
id: ID! @isUnique
facebookUserId: String @isUnique
facebookEmail: String
createdAt: DateTime!
updatedAt: DateTime!
}
type AuthenticateFacebookUserPayload {
token: String!
}
extend type Mutation {
authenticateFacebookUser(facebookToken: String!) @resolver(function: "facebook-auth"): AuthenticateFacebookUserPayload
}
Most helpful comment
I ment a serverside subscription like in the example above:
What I am trying to understand is whether we should keep the
handlerterminology or we should simply call itresolverin all places.@marktani @nikolasburk @timsuchanek I would love some input on this :-)