Els escalars personalitzats en GraphQL permeten definir tipus de dades específics que no estan coberts pels tipus escalars predeterminats (com Int
, Float
, String
, Boolean
i ID
). Aquests tipus personalitzats són útils quan necessitem validar o transformar dades específiques abans de processar-les.
Conceptes clau
- Definició d'un escalar personalitzat: Es defineix en l'esquema de GraphQL.
- Implementació de l'escalar: Es crea una lògica per a la serialització, deserialització i validació de les dades.
- Ús en l'esquema: S'utilitza com qualsevol altre tipus en l'esquema de GraphQL.
Exemple pràctic: Definició d'un escalar personalitzat per a una adreça de correu electrònic
- Definició de l'escalar en l'esquema
Primer, definim l'escalar en el nostre esquema de GraphQL:
- Implementació de l'escalar
Després, implementem la lògica per a l'escalar. En aquest exemple, utilitzarem JavaScript amb la biblioteca graphql-tools
per crear un escalar personalitzat que validi adreces de correu electrònic.
// emailScalar.js const { GraphQLScalarType, Kind } = require('graphql'); const validateEmail = (value) => { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (typeof value !== 'string' || !emailRegex.test(value)) { throw new TypeError(`Value is not a valid email: ${value}`); } return value; }; const Email = new GraphQLScalarType({ name: 'Email', description: 'A custom scalar type for email addresses', serialize: validateEmail, parseValue: validateEmail, parseLiteral(ast) { if (ast.kind !== Kind.STRING) { throw new TypeError(`Value is not a valid email: ${ast.value}`); } return validateEmail(ast.value); }, }); module.exports = Email;
- Integració de l'escalar en l'esquema
Ara, integrem l'escalar en el nostre esquema i resolvers:
// schema.js const { makeExecutableSchema } = require('@graphql-tools/schema'); const Email = require('./emailScalar'); const typeDefs = ` scalar Email type User { id: ID! email: Email! } type Query { user(id: ID!): User } type Mutation { createUser(email: Email!): User } `; const resolvers = { Email, Query: { user: (parent, args, context, info) => { // Implementació de la consulta }, }, Mutation: { createUser: (parent, args, context, info) => { // Implementació de la mutació }, }, }; const schema = makeExecutableSchema({ typeDefs, resolvers, }); module.exports = schema;
- Ús de l'escalar en consultes i mutacions
Amb l'escalar definit i implementat, podem utilitzar-lo en les nostres consultes i mutacions:
# Exemple de consulta query GetUser($id: ID!) { user(id: $id) { id email } } # Exemple de mutació mutation CreateUser($email: Email!) { createUser(email: $email) { id email } }
Exercici pràctic
Exercici
Crea un escalar personalitzat per a validar números de telèfon. El número de telèfon ha de seguir el format internacional (per exemple, +1234567890).
- Defineix l'escalar
PhoneNumber
en l'esquema. - Implementa la lògica de validació per a l'escalar.
- Integra l'escalar en l'esquema i crea una mutació
createUser
que accepti unPhoneNumber
.
Solució
1. Definició de l'escalar en l'esquema
2. Implementació de l'escalar
// phoneNumberScalar.js const { GraphQLScalarType, Kind } = require('graphql'); const validatePhoneNumber = (value) => { const phoneRegex = /^\+\d{10,15}$/; if (typeof value !== 'string' || !phoneRegex.test(value)) { throw new TypeError(`Value is not a valid phone number: ${value}`); } return value; }; const PhoneNumber = new GraphQLScalarType({ name: 'PhoneNumber', description: 'A custom scalar type for phone numbers', serialize: validatePhoneNumber, parseValue: validatePhoneNumber, parseLiteral(ast) { if (ast.kind !== Kind.STRING) { throw new TypeError(`Value is not a valid phone number: ${ast.value}`); } return validatePhoneNumber(ast.value); }, }); module.exports = PhoneNumber;
3. Integració de l'escalar en l'esquema
// schema.js const { makeExecutableSchema } = require('@graphql-tools/schema'); const PhoneNumber = require('./phoneNumberScalar'); const typeDefs = ` scalar PhoneNumber type User { id: ID! phoneNumber: PhoneNumber! } type Query { user(id: ID!): User } type Mutation { createUser(phoneNumber: PhoneNumber!): User } `; const resolvers = { PhoneNumber, Query: { user: (parent, args, context, info) => { // Implementació de la consulta }, }, Mutation: { createUser: (parent, args, context, info) => { // Implementació de la mutació }, }, }; const schema = makeExecutableSchema({ typeDefs, resolvers, }); module.exports = schema;
Resum
En aquesta secció, hem après a crear escalars personalitzats en GraphQL per validar i transformar dades específiques. Hem vist com definir l'escalar en l'esquema, implementar la lògica de validació i integrar-lo en les nostres consultes i mutacions. Els escalars personalitzats són una eina poderosa per assegurar la integritat de les dades en les nostres aplicacions GraphQL.
Curs de GraphQL
Mòdul 1: Introducció a GraphQL
- Què és GraphQL?
- GraphQL vs REST
- Configuració d'un servidor GraphQL
- Conceptes bàsics de l'esquema de GraphQL
Mòdul 2: Conceptes bàsics
Mòdul 3: Disseny avançat d'esquemes
Mòdul 4: Treballant amb dades
- Connexió a una base de dades
- Estratègies de recuperació de dades
- Agrupació i emmagatzematge en memòria cau
- Gestió d'errors
Mòdul 5: Rendiment i seguretat
Mòdul 6: Eines i ecosistema
Mòdul 7: Proves i desplegament
- Proves unitàries de resolvers
- Proves d'integració
- Integració contínua
- Desplegament de servidors GraphQL