【问题标题】:Extending types with ObjectType field使用 ObjectType 字段扩展类型
【发布时间】:2021-02-18 06:07:32
【问题描述】:

我是 HotChocolate 和 GraphQL 的新手,我在类型扩展方面遇到了一些困难。

是否可以使用ObjectType 字段扩展类型?我在StringType 的文档中只找到了一个示例:

protected override void Configure(IObjectTypeDescriptor descriptor)
{
    descriptor.Name("Person");
    descriptor.Field("address")
        .Type<StringType>()
        .Resolver("Address");
}

我尝试做类似的事情,但我有这个例外HotChocolate.SchemaException: Unable to resolve type reference Output: ObjectType

protected override void Configure(IObjectTypeDescriptor descriptor)
{
    descriptor.Name("Person");
    descriptor.Field("address")
        .Type<ObjectType>()
        .Resolver(ctx => new ObjectType(d => d.Field("street").Type<StringType>().Resolver("Street")));
}

在我的情况下,您能否建议任何使用 ObjectType 字段扩展类型的方法?还是直接回答有没有可能?

谢谢!

【问题讨论】:

  • 扩展你make的目的其实并不清楚。您能否提供有关您认为导致该需求的用例的更详细信息?根据您的示例:似乎更自然的方法是定义类型地址及其元数据类型(公共类地址类型:ObjectType
    {...})。
  • 我的实体中的一个字段是用户在运行时配置的 json 对象。所以我无法提前描述一个合适的对象。但我希望能够在 GraphQL 架构中显示此 json 包含的字段。
  • Schema 是在使用之前设置的东西。例如,HotChocolate v.11 在启动时编译模式,所以,我不确定它是否是在运行时更改它的正确方法。以属性名称作为键来呈现 JSON 对象(如字典)可能更合适。
  • 其实我在应用启动的时候就知道方案,而且它的整个生命周期都不会改变。所以我认为在 GraphQL 模式中显示它会很有用。

标签: hotchocolate


【解决方案1】:

假设,您的类 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
        }
      }
    ]
  }
}

【讨论】:

  • 谢谢!但是,如果我不仅有简单类型(如StringTypeIntTypeDecimalType),而且还有其他在DataType 内具有未知结构的对象,该怎么办?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-13
  • 1970-01-01
  • 2015-08-21
  • 2022-09-24
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
相关资源
最近更新 更多