graphql

2020-12-16T20:41:58.109800Z

I’m a bit confused about lacinia’s support for directives. They are parsed, and I believe you can access them in resolvers, but is it also possible to add global behaviour to them? For example, GitHub’s schema defines a custom @possibleTypes directive that constraints inputs of type ID to references to particular concrete or abstract types, say @possibleTypes(concreteTypes: ["User"]). Is that something I can do in Lacinia?

isak 2020-12-16T22:16:56.110800Z

How about wrapping all of your resolvers before handing the schema to compile ?

hlship 2020-12-17T17:01:30.123Z

This is what I'm working at; however I think ultimately there will be a callback that allows you to wrap all resolvers in the schema that have directives on them, so that we could leverage the new APIs recently introduced to expose directives.

1
hlship 2020-12-17T17:02:45.123200Z

At some point, we either need to add some new abstractions to allow directives to manipulate the intermediate representation of the schemas and queries, or document and stabilize the data structures that are present.

hlship 2020-12-17T17:04:47.123400Z

The goal would be that application-specific directives could do anything the built in @include and @skip directives do (though note that those are called out specially in the spec).

hlship 2020-12-17T17:05:02.123600Z

In any case, currently left as an exercise for the reader.

2
2020-12-16T22:32:32.113100Z

Hmm yeah, I could wrap all my mutations, and check ID’s to be of some particular concrete type (as far as I can tell, there are no resolvers for input types, so has to be mutations I guess). I found GHs example with the custom directive pretty elegant, so I was also wondering whether that was possible too ^^

isak 2020-12-16T22:38:42.114900Z

For queries, you can check the all the arguments in the field resolvers, no? @lennart.buit

2020-12-16T22:59:43.117800Z

Right, yeah. I can add validation logic to all my mutation resolvers to check that global id’s are of the correct types. I was hoping to do it declaratively & automatically generate validation logic. For example, this is a simple mutation in ‘GH’ style (as per their publicly available schema), so I was specifically wondering whether I could implement a similar directive with Lacinia:

mutation {
  addLabelToLabelable(input: AddLabelToLabelableInput!): AddLabelToLabelablePayload!
}

type AddLabelToLabelablePayload {
  labelable: Labelable
}

input AddLabelToLabelableInput {
  id: ID! @possibleTypes(abstractType: "Labelable") # Validation failure if you give some global id that is not considered Labelable. I'd assume automatically checked.
  label: String
}

2020-12-16T23:00:57.118400Z

(I thought it was an interesting approach, so I was just wondering whether it is possible, haha 🙂!)

isak 2020-12-16T23:04:57.119300Z

For an easy API, I see this in the manual: > Directive support is evolving quickly; full support for directives, including argument type validation, is forthcoming (emphasis mine)

isak 2020-12-16T23:06:28.120500Z

Otherwise, if you can't wait, changing line 54 would enable you to add your own validations: https://github.com/walmartlabs/lacinia/blob/master/src/com/walmartlabs/lacinia.clj#L30-L62

2020-12-16T23:20:11.122600Z

I think I may be able to combine both :thinking_face:, do indeed map over the mutation resolvers, and generate new ones that check in the selections whether there are directives and if so check the validation rules of those directives on inputs (I’m hopeful that https://github.com/walmartlabs/lacinia/pull/335 helps me in that!). Thanks!

3