Исходный код вики Сценарии
Редактировал(а) Alexandr Fokin 2024/03/05 20:34
Последние авторы
author | version | line-number | content |
---|---|---|---|
1 | |(% style="width:144px" %)Выполнить запрос из кода|(% style="width:1349px" %)((( | ||
2 | ASP.NET Core API with GraphQL request using HotChocolate in itself | ||
3 | [[https:~~/~~/stackoverflow.com/questions/73652499/asp-net-core-api-with-graphql-request-using-hotchocolate-in-itself>>https://stackoverflow.com/questions/73652499/asp-net-core-api-with-graphql-request-using-hotchocolate-in-itself]] | ||
4 | |||
5 | |||
6 | В случае, если подключен через DI. | ||
7 | |||
8 | {{code language="c#"}} | ||
9 | var resolver = scope.ServiceProvider.GetRequiredService<IRequestExecutorResolver>(); | ||
10 | var executor = await resolver.GetRequestExecutorAsync(); | ||
11 | |||
12 | using var result = await executor.ExecuteAsync(query); | ||
13 | var resultJson = await result.ToJsonAsync(); | ||
14 | {{/code}} | ||
15 | ))) | ||
16 | |(% style="width:144px" %)Парсер запросов|(% style="width:1349px" %){{code language="c#"}}var bytes = Encoding.UTF8.GetBytes(jsonRequest); | ||
17 | var requestData = new Span<byte>(bytes); | ||
18 | requestData = requestData.Slice(0, bytes.Length); | ||
19 | |||
20 | var parser = new Utf8GraphQLRequestParser(requestData); | ||
21 | return parser.Parse();{{/code}} | ||
22 | |(% style="width:144px" %)Перехват IQueryable|(% style="width:1349px" %){{code language="c#"}}public class IQueryableInterceptorAttribute | ||
23 | : ObjectFieldDescriptorAttribute | ||
24 | { | ||
25 | public IQueryableInterceptorAttribute([CallerLineNumber] int order = 0) | ||
26 | { | ||
27 | Order = order; | ||
28 | } | ||
29 | |||
30 | public override void OnConfigure( | ||
31 | IDescriptorContext context, | ||
32 | IObjectFieldDescriptor descriptor, | ||
33 | MemberInfo member | ||
34 | ) | ||
35 | { | ||
36 | descriptor | ||
37 | .Use( | ||
38 | next => async context => | ||
39 | { | ||
40 | await next(context); | ||
41 | |||
42 | var scope = GraphQLIQueryableScope.Current; | ||
43 | |||
44 | if (scope is not null) | ||
45 | { | ||
46 | scope.SetData(context.Result!); | ||
47 | context.Result = null; | ||
48 | } | ||
49 | } | ||
50 | ); | ||
51 | } | ||
52 | }{{/code}} | ||
53 | |(% style="width:144px" %)Вычисляемые и внешние данные.|(% style="width:1349px" %)((( | ||
54 | 1) Используя механизм | ||
55 | |||
56 | Extending Types | ||
57 | [[https:~~/~~/chillicream.com/docs/hotchocolate/v13/defining-a-schema/extending-types>>https://chillicream.com/docs/hotchocolate/v13/defining-a-schema/extending-types]] | ||
58 | |||
59 | можно добавить к сущности дополнительные поля, при этом также есть возможность указать кастомную логику заполнения полей (Resolver). | ||
60 | Т.е. данные механизм можно использовать, чтобы сделать вычисляемый столбец и (или) столбец с данными на основе внешнего источника данных (например данных, которые не соединяются напрямую или же загружаются из внешнего web api). | ||
61 | |||
62 | {{code language="c#"}} | ||
63 | public static void AddScalarResolver<TEntity, TType, TResolverType>( | ||
64 | this IObjectTypeDescriptor<TEntity> descriptor, | ||
65 | string fieldName | ||
66 | ) | ||
67 | // Самодельный интерфейс для удобства, его нет в фреймворке. | ||
68 | where TResolverType : IDataResolver<TType> | ||
69 | { | ||
70 | descriptor | ||
71 | .Field(fieldName) | ||
72 | .Type<ScalarType<TType>>() | ||
73 | .ResolveWith<TResolverType>( | ||
74 | e => e.LoadAsync(default!, default) | ||
75 | ); | ||
76 | } | ||
77 | {{/code}} | ||
78 | |||
79 | ---- | ||
80 | |||
81 | 2) Добавив к вышеуказанному решению механизм | ||
82 | |||
83 | DataLoader | ||
84 | [[https:~~/~~/chillicream.com/docs/hotchocolate/v13/fetching-data/dataloader>>https://chillicream.com/docs/hotchocolate/v13/fetching-data/dataloader]] | ||
85 | |||
86 | а именно BatchDataLoader, можно оптимизировать запросы и вычисления. | ||
87 | Есть возможность выполнить пакетную обработку, выполнив предварительное извлечение всех необходимых параметров | ||
88 | (правда в виде одного объекта строки, но можно использовать сериализацию или отдельный типизированный объект-хранилище в сочетании с типом регистрации Scoped), | ||
89 | в рамках обработки одного входящего запроса. | ||
90 | |||
91 | ---- | ||
92 | |||
93 | 3) При всех вышеуказанном, мы можем использовать в качестве сущности БД из [[EntityFramework | EntityFrameworkCore>>doc:Разработка.NET.Работа с БД.EntityFramework | EntityFrameworkCore.WebHome]] контекста, при этом имея встроенный механизм выборки [[IQueryable>>doc:Разработка.NET.C#.Коллекции.IQueryable.WebHome||style="outline-width: 0px !important; user-select: auto !important;"]]. | ||
94 | ))) | ||
95 | |(% style="width:144px" %) |(% style="width:1349px" %) | ||
96 | |(% style="width:144px" %)[[Тестирование>>doc:Разработка.Тестирование.WebHome]]|(% style="width:1349px" %)GraphQL - How to write integration tests against Hot Chocolate | ||
97 | [[https:~~/~~/chillicream.com/blog/2019/04/11/integration-tests>>https://chillicream.com/blog/2019/04/11/integration-tests]] |