Attach metadata to your GraphQL schema using directive like syntax.
Library supoports following formats:
- (DEPRECATED) Annotations: Group of elements with common namespace. For example
@db.length: 200
- Marker: Single instance (key) with multiple values. For example
@db length:200
- Metadata: Directive-like config. For example
@db(length: 200, columns: ['id', 'name'])
npm i graphql-metadata
Markers using different syntax for elements that do not support grouping.
For example @marker true
etc.
Usage:
const result = parseMarker('db', `
This is a description
@db length:200, unique: true
`)
No value usage:
const result = parseMarker('db', `
This is a description
@db
`)
Metadata uses the same syntax as GraphQL directives.
Usage:
const field: GraphQLField<any,any> = {
...,
description: `@db(length:200,
unique: true,
columns: ['id', 'name']
description: 'Some description'
)`
}
const result = parseMetadata('db', field)
// Returns:
{
length:200,
unique: true,
columns: ['id', 'name']
description: 'Some description'
}
No value usage:
const field: GraphQLField<any,any> = {
...,
description: '@db',
}
const result = parseMetadata('db', field)
// Returns true
Or with a string:
const result = parseMetadata('db', '@db(name: "users")')
Here is a very basic example with a namespace
(here 'db'
) and a description
that needs to be parsed:
const { parseAnnotations } = require('graphql-metadata')
const result = parseAnnotations('db', `
This is a description
@db.length: 200
@db.foo: 'bar'
@db.unique
@db.index: { name: 'foo', type: 'string' }
`)
console.log(result)
This will output an object containing the annotations:
{
length: 200,
foo: 'bar',
unique: true,
index: { name: 'foo', type: 'string' }
}
In a GraphQL schema, you can use the description
property on GraphQLObjectType
, GraphQLField
...
const { parseAnnotations } = require('graphql-metadata')
const { buildSchema, isObjectType } = require('graphql')
const schema = buildSchema(`
"""
@db.table: 'users'
"""
type User {
"""
@db.primary
"""
id: ID!
}
`)
const typeMap = schema.getTypeMap()
for (const key in typeMap) {
const type = typeMap[key]
// Tables
if (isObjectType(type)) {
const typeAnnotations = parseAnnotations('db', type.description)
console.log(type.name, typeAnnotations)
const fields = type.getFields()
for (const key in fields) {
const field = fields[key]
const fieldAnnotations = parseAnnotations('db', field.description)
console.log(field.name, fieldAnnotations)
}
}
}
Which will output:
User { table: 'users' }
id { primary: true }
Sometimes it will be helpful to strip the annotations from the description. For example, you may not want to display them in a GraphQL schema explorer.
const { stripAnnotations } = require('graphql-metadata')
const result = stripAnnotations('db', `
This is a description
@db.length: 200
@db.foo: 'bar'
@db.unique
@db.index: { name: 'foo', type: 'string' }
`)
console.log(result)
The result will be:
`
This is a description
`