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
PhoneNumberen l'esquema. - Implementa la lògica de validació per a l'escalar.
- Integra l'escalar en l'esquema i crea una mutació
createUserque 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
