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

  1. Definició d'un escalar personalitzat: Es defineix en l'esquema de GraphQL.
  2. Implementació de l'escalar: Es crea una lògica per a la serialització, deserialització i validació de les dades.
  3. Ú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

  1. Definició de l'escalar en l'esquema

Primer, definim l'escalar en el nostre esquema de GraphQL:

# schema.graphql
scalar Email

  1. 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;

  1. 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;

  1. Ú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).

  1. Defineix l'escalar PhoneNumber en l'esquema.
  2. Implementa la lògica de validació per a l'escalar.
  3. Integra l'escalar en l'esquema i crea una mutació createUser que accepti un PhoneNumber.

Solució

1. Definició de l'escalar en l'esquema

# schema.graphql
scalar PhoneNumber

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.

© Copyright 2024. Tots els drets reservats