GraphQL trabaja con sus propios tipos de datos, por lo tanto debemos mapear nuestro modelo a los tipos de datos de GraphQL, a continuación se muestra una tabla con la equivalencia de los tipos de datos.
.NET | GraphQL .NET |
string | StringGraphType |
int, long | IntGraphType |
double | FloatGraphType |
bool | BooleanGraphType |
DateTime (Date) | DateGraphType |
DateTime | DateTimeGraphType |
TimeSpan (Seconds) | TimeSpanSecondsGraphType |
Milliseconds | TimeSpanMillisecondsGraphType |
GraphQL necesita clases que hereden del tipo ObjectGraphType para los métodos GET, vamos a crear las siguientes clases: CaducidadType, ClienteType y ProductoType. Con estas clases podemos obtener ya sea únicamente los datos de un producto, un cliente o los datos de la caducidad que incluyan los datos del cliente y del producto.
Creamos una carpeta GraphQL en nuestro proyecto, luego creamos una carpeta Types. Agregamos una descripción para la documentación de nuestros servicios, para el caso de cliente solo voy a mostrar algunos campos de nuestra tabla Cliente
ClienteType.csusing System;using CaducaRest.Models;using CaducaRest.Resources;using GraphQL.Types;namespace CaducaRest.GraphQL.Types{/// <summary>/// GraphQL tiene sus propios tipos de datos por lo que/// es necesario crear un objeto de tipo ObjectGraphType/// para mapear los campos del objeto con los de GraphQL/// </summary>public class ClienteType : ObjectGraphType<Cliente>{/// <summary>/// Constructor para mapear los campos/// </summary>/// <param name="locService">Para mensajes de error en varios idiomas</param>public ClienteType( LocService locService){Name = "Cliente";Field(c => c.Id).Description("Id");Field(c => c.Clave).Description("Clave del producto");Field(c => c.NombreComercial).Description("Nombre comercial del cliente");Field(c => c.RazonSocial).Description("Razón Social");}}}
Creamos el tipo de Producto
ProductoType.cspublic class ProductoType : ObjectGraphType<Producto>{public ProductoType(LocService locService){Name = "Producto";Field(c => c.Id).Description("Id");Field(c => c.Clave).Description("Clave del producto");Field(c => c.Nombre).Description("Nombre del cliente");Field(c => c.CategoriaId).Description("Categoria");}}
Para el caso de Caducidad, agregamos como Field nuestro tipo de dato para cliente y para producto, agregamos una propiedad arguments para pasar como parámetro el Id del producto y con la propiedad resolve indicamos el objeto que va a traer la información para llenar los datos producto. Realizamos lo mismo para nuestra tabla Cliente.
using CaducaRest.DAO;using CaducaRest.Models;using CaducaRest.Resources;using GraphQL.Types;using Microsoft.Extensions.DependencyInjection;namespace CaducaRest.GraphQL.Types{/// <summary>/// Caducidad type./// </summary>public class CaducidadType : ObjectGraphType<Caducidad>{/// <summary>/// Constructor <see cref="T:CaducaRest.GraphQL.Types.CaducidadType"/> class./// </summary>/// <param name="caducaContext">Caduca context.</param>/// <param name="locService">Location service.</param>public CaducidadType(LocService locService){Name = "Caducidad";Field(c => c.Id).Description("Id");Field(c => c.ProductoId).Description("Id del producto");Field(c => c.ClienteId).Description("Id del cliente");Field(c => c.Cantidad).Description("Cantidad");Field(c => c.Fecha).Description("Fecha");Field<ProductoType>("Producto",arguments: new QueryArguments(new QueryArgument<IntGraphType> { Name = "Id" }),resolve: context =>{using var scope = context.RequestServices.CreateScope();var services = scope.ServiceProvider;var caducaContext = services.GetRequiredService<CaducaContext>();ProductoDAO productoDAO = new ProductoDAO(caducaContext, locService);return productoDAO.ObtenerPorIdAsync(context.Source.Id).Result;});Field<ClienteType>("Cliente",arguments: new QueryArguments(new QueryArgument<IntGraphType> { Name = "Id" }),resolve: context => {using var scope = context.RequestServices.CreateScope();var services = scope.ServiceProvider;var caducaContext = services.GetRequiredService<CaducaContext>();ClienteDAO clienteDAO = new ClienteDAO(caducaContext, locService);return clienteDAO.ObtenerPorIdAsync(context.Source.Id).Result;});}}}
Para los métodos POST y PUT las clases deben heredar del tipo InputObjectGraphType en este ejemplo solo voy a crear la clase CaducidadInputType para agregar nuevas caducidades agregamos todos los campos de nuestro modelo Caducidad
CaducidadInputType.cspublic class CaducidadInputType: InputObjectGraphType{public CaducidadInputType(){Name = "CaducidadInput";Field<NonNullGraphType<IntGraphType>>("Id");Field<NonNullGraphType<IntGraphType>>("Cantidad");Field<NonNullGraphType<IntGraphType>>("ProductoId");Field<NonNullGraphType<IntGraphType>>("ClienteId");Field<NonNullGraphType<DateGraphType>>("Fecha");}}
Puedes consultar la documentación oficial aquí: