In this tutorial i will show how to implement an Email custom scalar to Apollo GraphQL.
Implement an email scalar isn’t a hard task but i will show in details.
You must implement the functions __parseValue, __serialize and __parseLiteral.
We need a regex to check the email, in this tutorial i used this one:
First we must implement the __parseValue function. Basically we will just test the input type and check the input with our Regex:
After this we will implement the __serialize function , in our example let’s just return the value:
And finally lets implement the __parseLiteral function , we will check the literal kind and check our regex with literal value:
And that’s it ! Our email custom scalar is done. You can check the complete code and the unit test below:
import { gql } from 'apollo-server-express' | |
import { GraphQLError } from 'graphql/error' | |
import { Kind } from 'graphql/language' | |
const EMAIL_REGEX = new RegExp( | |
/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/ | |
) | |
const Email = gql` | |
"Scalar data representing email" | |
scalar Email | |
` | |
/* eslint-disable no-underscore-dangle */ | |
export const resolver = { | |
Email: { | |
__parseValue(value) { | |
if (typeof value !== 'string') { | |
throw new TypeError('Value is not string') | |
} | |
if (!EMAIL_REGEX.test(value)) { | |
throw new TypeError(`Value is not a valid email address: ${value}`) | |
} | |
return value | |
}, | |
__serialize(value) { | |
return value | |
}, | |
__parseLiteral(ast) { | |
if (ast.kind !== Kind.STRING) { | |
throw new GraphQLError( | |
`Value is not string : ${ast.kind}` | |
) | |
} | |
if (!EMAIL_REGEX.test(ast.value)) { | |
throw new GraphQLError(`Value is not a valid email address: ${ast.value}`) | |
} | |
return ast.value | |
} | |
} | |
} | |
export default () => [ | |
] |
import { Kind } from 'graphql/language' | |
import { resolver } from '../src/graphql/schema/types/scalar/email' | |
/* eslint-disable no-underscore-dangle */ | |
const email = 'test@test' | |
const emailComplete = 'test@test.com' | |
describe('Email scalar', () => { | |
describe('when email is valid', () => { | |
it('serialize correctly with complete email', () => { | |
expect(resolver.Email.__serialize(emailComplete)) | |
.to | |
.eql(emailComplete) | |
}) | |
it('serialize correctly', () => { | |
expect(resolver.Email.__serialize(email)) | |
.to | |
.eql(email) | |
}) | |
it('parseValue correctly with complete email', () => { | |
expect(resolver.Email.__parseValue(emailComplete)) | |
.to | |
.eql(emailComplete) | |
}) | |
it('parseValue correctly', () => { | |
expect(resolver.Email.__parseValue(email)) | |
.to | |
.eql(email) | |
}) | |
it('parseLiteral correctly with complete email', () => { | |
expect( | |
resolver.Email.__parseLiteral({ | |
value: emailComplete, | |
kind: Kind.STRING | |
}, {}) | |
) | |
.to | |
.eql(emailComplete) | |
}) | |
it('parseLiteral correctly', () => { | |
expect( | |
resolver.Email.__parseLiteral({ | |
value: email, | |
kind: Kind.STRING | |
}, {}) | |
) | |
.to | |
.eql(email) | |
}) | |
}) | |
describe('when email is invalid', () => { | |
describe('and not a string', () => { | |
it('parseValue', () => { | |
expect(() => resolver.Email.__parseValue(435)) | |
.to | |
.throw( | |
'Value is not string' | |
) | |
}) | |
it('parseLiteral', () => { | |
expect(() => resolver.Email.__parseLiteral({ | |
value: '453', | |
kind: Kind.INT | |
}, {})) | |
.to | |
.throw('Value is not string : IntValue') | |
}) | |
}) | |
describe('and not an email address', () => { | |
it('parseValue', () => { | |
expect(() => resolver.Email.__parseValue('this is a test')) | |
.to | |
.throw('Value is not a valid email address: this is a test') | |
}) | |
it('parseLiteral', () => { | |
expect(() => resolver.Email.__parseLiteral({ | |
value: 'this is a test', | |
kind: Kind.STRING | |
}, {})) | |
.to | |
.throw('Value is not a valid email address') | |
}) | |
}) | |
}) | |
}) |
I hope this helps !
Top comments (0)