question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Setting directives using ObjectType constructor (not IDL)

See original GitHub issue

I am reviving #1262 as I have an use case that is related to that discussion:

Right now directives are purely a feature of the GraphQL language and IDL, so a schema not created using IDL definitionally won’t contain directives. When building a schema in code, you have the full power of the host programming environment, so directives shouldn’t be necessary. Directives are a tool for supplying additional intent to be later interpreted by the host programming environment.

You can include any arbitrary data on a GraphQLObjectType that you like - it’s just a JS object after all. Directives are a language-level feature, not a structural property of a type.

I agree that “directives are a tool for supplying additional intent” and “you have the full power of the host programming environment”. But since the GraphQL ecosystem has grown, I think we should think about interoperability with 3rd-party libraries. The examples that I am thinking about is Apollo cache control and Prisma, which are using directives to provide some metadata to make awesome underlaying features work.

As graphql-js doesn’t allow for registering directives using imperative way (ObjectType constructor), to be able to use Prisma, we are forced to use IDL to create our types. But this way might be not available when you are using the imperative way as you build a library on top of graphql-js, as well as when you would have to refactor your whole app by migrating to IDL to add apollo-cache integration.

So I think that now directives are a much more widespread feature and we should allow for interoperability with this 3rd-party tools.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:72
  • Comments:27 (19 by maintainers)

github_iconTop GitHub Comments

39reactions
rattrayalexcommented, Apr 16, 2021

I’d like to be able to construct a gql schema with a code-first tool like typegraphql, print the schema, and see what I constructed.

For example, I’d like to be able to write this:

@ObjectType()
class Bar {
  @Directive("@auth(requires: USER)")
  @Field()
  field: string;
}

and get this:

type Bar {
  field: String! @auth(requires: USER)
}

however, that isn’t possible today, due to this issue.

Sure, my directives will work fine at runtime, but I’d like to be able to look at my generated schema.graphql and see which fields require auth, or which are deprecated, or which have a high cost, or whatever.

It seems there’s some reticence to add support for storing directives because runtime tooling should ideally handle the functionality of directives in another manner, but this would be useful outside of runtime behavior, like looking at a textual schema with human eyeballs or a linter.

29reactions
nodkzcommented, Jul 2, 2018

The new Apollo Server v2 introduce requirements for graphql-compose (and graphql-js) users to somehow provide directive via GraphQL*Type classes for providing an info for CDN cache. Without providing directives via GraphQL*Type we have no way to use Apollo Server v2.

Another use case was with graphql-cost-analysis which allows rejecting complex queries. It provides a comfortable way to add a complexity calculation logic without modifying resolvers.

It will be cool if Lee changes its position according to directives.

Repeat here a desired way for declaration directives from #1262:

const UserType = new GraphQLObjectType({
  name: 'User',
  fields: {
    name: {
      type: GraphQLString,
      description: '...',
      resolve: () => ...,
      directives: [
        { name: 'cost',  args: { useMultipliers: false, complexity: 2 } },
        { name: 'unique' },
      ],
      // or maybe simpler if graphql spec does not allow duplicated names
      directives: {
        cost: { useMultipliers: false, complexity: 2 },
        unique: true,
      },
    },
  },
});
Read more comments on GitHub >

github_iconTop Results From Across the Web

Creating schema directives - Apollo GraphQL Docs
This method takes your executable schema, along the same form of directive map you provide to the schemaDirectives constructor option:.
Read more >
WebIDL Level 1 - W3C
The identifier of any of the abovementioned IDL constructs MUST NOT be “constructor”, “toString”, “toJSON”, or begin with a U+005F LOW LINE ...
Read more >
Introduction to Microsoft Interface Definition Language 3.0
The interface and runtimeclass reference types conceptually derive from the Object type; delegate does not. Expressions in an enumerated value.
Read more >
Domains - Sphinx documentation
Though, note that not every directive in every domain may support these options. New in version 3.2: The directive option noindexentry in the...
Read more >
IDL to Java Language Mapping Specification
Object Management Group specification in accordance with the license and notices set forth on this page. This document does not represent a commitment...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Hashnode Post

No results found