假设,您的类 Book 包含一些 JSON 字段“数据”。“数据”的结构可以在重新启动之间更改,但在任何启动之前都是已知的(即您在启动时知道属性名称及其类型)。以下代码解决了这种情况:
using System.Linq;
using HotChocolate.Resolvers;
using HotChocolate.Types;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Linq;
namespace Ademchenko.GraphQLWorkshop
{
public class Book
{
public int Id { get; set; }
public JObject Data { get; set; }
}
public interface IBookService { IQueryable<Book> GetAll(); }
public class InMemoryBookService : IBookService
{
private readonly Book[] _staticBooks = {
new Book {Id = 11, Data = JObject.FromObject(new {Title = "FooBook", AuthorId = 1, Price = 10.2m})},
new Book {Id = 22, Data = JObject.FromObject(new { Title = "BarBook", AuthorId = 2, Price = 20.2m})}
};
public IQueryable<Book> GetAll() => _staticBooks.AsQueryable();
}
public class Query
{
public IQueryable<Book> GetBooks(IResolverContext ctx) => ctx.Service<IBookService>().GetAll();
}
public class BookType : ObjectType<Book>
{
protected override void Configure(IObjectTypeDescriptor<Book> descriptor)
{
descriptor.Field(d => d.Data).Type<DataType>();
}
}
public class DataType : ObjectType
{
protected override void Configure(IObjectTypeDescriptor descriptor)
{
descriptor.Field("title").Type<StringType>().Resolve((ctx, ct) => (string)ctx.Parent<JObject>()["Title"]);
descriptor.Field("authorId").Type<IntType>().Resolve((ctx, ct) => (int)ctx.Parent<JObject>()["AuthorId"]);
descriptor.Field("price").Type<DecimalType>().Resolve((ctx, ct) => (decimal)ctx.Parent<JObject>()["AuthorId"]);
}
}
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration) => Configuration = configuration;
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSingleton<IBookService, InMemoryBookService>();
services.AddGraphQLServer()
.AddQueryType<Query>()
.AddType<BookType>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) => app.UseRouting().UseEndpoints(endpoints => endpoints.MapGraphQL());
}
}
向服务器发出请求:
{
books
{
id,
data
{
title
authorId
price
}
}
}
您将收到以下回复:
{
"data": {
"books": [
{
"id": 11,
"data": {
"title": "FooBook",
"authorId": 1,
"price": 1
}
},
{
"id": 22,
"data": {
"title": "BarBook",
"authorId": 2,
"price": 2
}
}
]
}
}