Исходный код вики Сценарии
Редактировал(а) 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]] |