The first step is to install three packages using GraphQL

GraphQL
GraphQL.Server.Transports.AspNetCore
GraphQL.Server.Ui.Playground
Copy the code

Defining base classes

public class Account
{
    public Guid Id { get; set; }
    public TypeOfAccount Type { get; set; }
    public string Description { get; set; }

    public Guid PersonId { get; set; }
    public Person Person { get; set; }}public enum TypeOfAccount
{
    Invalid,
    Free,
    Junior,
    Intermediate
}
Copy the code
public class Person
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }

    public ICollection<Account> Accounts { get; set; }}Copy the code

context

public class SampleContext
{
    public List<Person> Persons { get; set; }
    public List<Account> Accounts { get; set; }

    public SampleContext()
    {
        var ids = new[] { Guid.NewGuid(), Guid.NewGuid() };

        Accounts = new List<Account>
        {
            new Account
            {
                Id = Guid.NewGuid(),
                Type = TypeOfAccount.Junior,
                Description = "Junior Member",
                PersonId = ids[0]},new Account
            {
                Id = Guid.NewGuid(),
                Type = TypeOfAccount.Intermediate,
                Description = "Intermediate Member",
                PersonId = ids[1]},new Account
            {
                Id = Guid.NewGuid(),
                Type = TypeOfAccount.Free,
                Description = "Free membership",
                PersonId = ids[1]}}; Persons =new List<Person>
        {
            new Person
            {
                Id = ids[0],
                Name = "Zhang",
                Address = "Beijing"
            },
            new Person
            {
                Id = ids[1],
                Name = "Bill",
                Address = "Shanghai"}}; }}Copy the code

warehousing

public interface IAccountRepository
{
    IEnumerable<Account> GetAllAccountsPerson(Guid personId);
}
public interface IPersonRepository
{
    IEnumerable<Person> GetAll();
    Person GetById(Guid id);
}
Copy the code
public class AccountRepository : IAccountRepository
{
    private readonly SampleContext _context;

    public AccountRepository(SampleContext context)
    {
        _context = context;
    }

    public IEnumerable<Account> GetAllAccountsPerson(Guid personId)
    {
        return_context.Accounts.Where(a => a.PersonId == personId); }}public class PersonRepository : IPersonRepository
{
    private readonly SampleContext _context;

    public PersonRepository(SampleContext context)
    {
        _context = context;
    }

    public IEnumerable<Person> GetAll()
    {
        return _context.Persons;
    }

    public Person GetById(Guid id)
    {
        return_context.Persons.SingleOrDefault(p => p.Id == id); }}Copy the code

GraphQL related classes

public class AccountTypeEnumType : EnumerationGraphType<TypeOfAccount>
{
    public AccountTypeEnumType()
    {
        Name = "Type"; }}Copy the code
public class AccountType : ObjectGraphType<Account>
{
    public AccountType()
    {
        Field(x => x.Id, type: typeof(IdGraphType));
        Field(x => x.Description);
        Field(x => x.PersonId, type: typeof(IdGraphType));
        Field<AccountTypeEnumType>("Type"."Enumeration of objects of type Account"); }}Copy the code
public class PersonType : ObjectGraphType<Person>
{
    public PersonType(IAccountRepository repository)
    {
        Field(x => x.Id, type: typeof(IdGraphType));
        Field(x => x.Name);
        Field(x => x.Address);
        Field<ListGraphType<AccountType>>(
            name: "accounts", resolve: context => repository.GetAllAccountsPerson(context.Source.Id)); }}Copy the code
public class AppSchema: Schema
{
    public AppSchema(IDependencyResolver resolver)
        :base(resolver){ Query = resolver.Resolve<AppQuery>(); }}Copy the code
public class AppQuery: ObjectGraphType
{
    public AppQuery(IPersonRepository repository)
    {
        Field<ListGraphType<PersonType>>(
            "persons",
            resolve: context => repository.GetAll()
        );

        Field<PersonType>(
            "person",
            arguments: new QueryArguments(new QueryArgument<NonNullGraphType<IdGraphType>> { Name = "personId" }),
            resolve: context =>
            {
                var personId = context.GetArgument<string> ("personId");

                if (Guid.TryParse(personId, out var id)) return repository.GetById(id);

                context.Errors.Add(new ExecutionError("Wrong GUID format"));
                return null; }); }}Copy the code

Used in ASP.NET Core

public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            services.AddSingleton<SampleContext>();

            services.AddScoped<IPersonRepository, PersonRepository>();
            services.AddScoped<IAccountRepository, AccountRepository>();

            services.AddScoped<IDependencyResolver>(s => new FuncDependencyResolver(s.GetRequiredService));
            services.AddScoped<AppSchema>();
 
            services.AddGraphQL(o => { o.ExposeExceptions = false; })
                .AddGraphTypes(ServiceLifetime.Scoped);

            services.Configure<KestrelServerOptions>(options =>
            {
                options.AllowSynchronousIO = true;
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

            app.UseGraphQL<AppSchema>();
            app.UseGraphQLPlayground(options: newGraphQLPlaygroundOptions()); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }}Copy the code

Use localhost: 5000 / UI/playgroud service to view the page

The client is used as follows:

public class PersonConsumer
{
    private readonly IGraphQLClient _client;

    public PersonConsumer(IGraphQLClient client)
    {
        _client = client;
    }

    public async Task<List<Person>> GetAll()
    {
        var query = new GraphQLRequest
        {
            Query = @" query personsQuery{ persons { id, name, address, accounts { id, type, description } } }"
        };

        var response = await _client.SendQueryAsync<ResponsePersonCollectionType>(query);
        return response.Data.Persons;
    }

    public async Task<Person> Get(string id)
    {
        var query = new GraphQLRequest
        {
            Query = @" query personQuery($personID: ID!) { person(personId: $personID) { id, name, address, accounts { id, type, description } } }",
            Variables = new { personID = id }
        };

        var response = await _client.SendQueryAsync<ResponsePersonType>(query);
        returnresponse.Data.Person; }}Copy the code
[Route("api/[controller]")]
[ApiController]
public class PersonController : ControllerBase
{
    private readonly PersonConsumer _personConsumer;

    public PersonController(PersonConsumer personConsumer)
    {
        _personConsumer = personConsumer;
    }

    public async Task<IActionResult> Get()
    {
        var persons = await _personConsumer.GetAll();
        return Ok(persons);
    }

    [HttpGet("{id}")]
    public async Task<IActionResult> Get(string id)
    {
        var person = await _personConsumer.Get(id);
        returnOk(person); }}Copy the code
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<IGraphQLClient>(s =>
            new GraphQLHttpClient(Configuration["GraphQLUri"].new NewtonsoftJsonSerializer()));

        services.AddScoped<PersonConsumer>();

        services.AddControllers();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if(env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }}Copy the code