Skip to content

Instantly share code, notes, and snippets.

@dandean
Last active June 3, 2019 08:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dandean/731b665c94dd0327ff1e91f0ab6cee09 to your computer and use it in GitHub Desktop.
Save dandean/731b665c94dd0327ff1e91f0ab6cee09 to your computer and use it in GitHub Desktop.
GraphQL Directive to Rename a Field from Source to Schema Context
directive @fromSourceField(name: String!) on FIELD
"""
This is a Contact type where the data source uses type-specific field names
for their ID fields. In this case we're renaming this field to `id` instead
of `contact_id`, making it much more friendly to the consuming application.
"""
type Contact {
id: ID! @fromSourceField(name: "contact_id")
...
}
import { SchemaDirectiveVisitor } from 'graphql-tools';
export default class FromSourceFieldsDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field) {
// The "name" argument given to the directive, ie `@fromSourceField(name: "contact_id")`
const { name } = this.args;
const { defaultFieldResolver } = field;
field.resolve = async (object, args, context, info) => {
object[field.name] = object[name];
return resolve.call(this, object, args, context, info);
};
}
}
// If you're using something like apollo-server, this is how you'd make the directive available:
import { makeExecutableSchema } from 'graphql-tools';
import FromSourceField from './FromSourceField.js';
// import or declare your typeDefs and resolvers - that process depends on your local setup.
const schema = makeExecutableSchema({
typeDefs,
resolvers,
// Add your custom directives:
schemaDirectives: {
fromSourceField: FromSourceField
}
});
// Then pass the schema to your server...
@steebchen
Copy link

It seems this only works when using a resolver and not a plain type. Any hint on how to implement this?

For example, when I return an object in my resolver:

return { contact_id: 'foo' }

with my GraphQL schema:

type Contact {
  id: ID! @fromSourceField(name: "contact_id")
  ...
}

it doesn't work since there is no field.resolve (and when adding one it will be ignored).

@ferdelamad
Copy link

@steebchen fix the issue and published a package: https://www.npmjs.com/package/apollo-directives

@naishe
Copy link

naishe commented Jun 3, 2019

I am going to try this package out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment