8.1.2 Creando Types

GraphQL trabaja con sus propios tipos de datos, por lo tanto debemos mapear nuestro modelo a los tipos de datos de GrapQL, a continuación se muetra 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

Miliseconds

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 unicamente 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.cs
using 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.cs
public 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>
/// Initializes a new instance of the <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.cs
public 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í: