Avanade

coreex-graphql

"Add or extend GraphQL-lite query support (CoreEx.Data.GraphQL) on a CoreEx *.Api host. USE FOR: first-time AddCoreExGraphQLLite/MapCoreExGraphQLLite wiring in Program.cs, registering AddQuery/AddGet roots over an entity's existing QueryArgsConfig, bulk-exposing reference data via AddReferenceDataQueries, adding a matching GraphQL root for an endpoint coreex-api just scaffolded, recording GraphQL enablement in the host's AGENTS.md. DO NOT USE FOR: REST controller endpoints (use coreex-api), defining or changing a QueryArgsConfig itself (use coreex-repository or coreex-refdata), general Program.cs setup unrelated to GraphQL (use coreex-scaffold)."

Avanade 28 8 Updated 4w ago

Resources

1
GitHub

Install

npx skillscat add avanade/coreex/coreex-graphql

Install via the SkillsCat registry.

SKILL.md

CoreEx: GraphQL-Lite Query Bridge

Guides you through adding CoreEx.Data.GraphQL (GraphQL-lite) to an *.Api host — wiring Program.cs, registering query/get roots over entities' existing QueryArgsConfig, optionally bulk-exposing reference data, and recording the enablement in that host's AGENTS.md.

When to Use

  • First time a host needs a GraphQL query surface — only when explicitly asked, never proactively
  • Adding a new AddQuery/AddGet root for an entity that already has a QueryArgsConfig + QueryAsync/GetAsync on its read service
  • Bulk-exposing reference data types as GraphQL roots via AddReferenceDataQueries
  • coreex-api just scaffolded a query endpoint on a host that already has GraphQL enabled, and the user wants a matching root added

When Not to Use

  • REST controller/endpoint work — use coreex-api
  • Defining or changing a QueryArgsConfig itself — use coreex-repository (entity queries) or coreex-refdata (reference data queries). GraphQL-lite only bridges to the existing config; it never adds new filter/sort capability of its own
  • General host Program.cs setup unrelated to GraphQL — use coreex-scaffold
  • Subscribe/Relay hosts — GraphQL-lite is a REST-adjacent query surface for *.Api hosts only

Quick Reference

Clarifying questions before writing any code:
0. Check the target host's AGENTS.md "This Host's Feature Configuration" section for an existing **GraphQL:** line — if already enabled, skip Program.cs wiring and go straight to root registration.

  1. Which *.Api host?
  2. First-time enablement, or adding a root to an already-enabled host?
  3. Which entities/read services get a root? (each must already have a QueryArgsConfig + QueryAsync/GetAsync)
  4. Also bulk-expose reference data via AddReferenceDataQueries? (default: Yes)
  5. Enable introspection (GraphQLLiteOptions.EnableIntrospection)? (default: No — secure-by-default)
  6. Require authorization on the endpoint (configure: rb => rb.RequireAuthorization())? (default: match the host's other endpoints — anonymous otherwise)

Key rules at a glance:

  • Additive and opt-in — never add without an explicit ask
  • Register via builder.Services.AddCoreExGraphQLLite((o, sp) => o.AddQuery<T>(...).AddGet<T>(...)); map via app.MapCoreExGraphQLLite("/query") after app.MapControllers()
  • Never bypass a QueryArgsConfig to add GraphQL-only filter/sort capability — extend the entity's existing config instead, so REST and GraphQL stay in exact lockstep
  • Resolve scoped services per-invocation via CoreEx.ExecutionContext.GetRequiredService<T>() — IGraphQLEngine is a singleton; never capture a scoped instance from the root IServiceProvider at registration time
  • AddReferenceDataQueries(sp, ReferenceDataQueryArgsConfig.Default) bulk-registers every ref-data type known to ReferenceDataOrchestrator, keyed ref_<name> (alternate name where registered, else Type.Name); pass excludeTypes to opt specific types out
  • Add .WithCoreExGraphQLTelemetry() alongside the host's other OpenTelemetry tracing extensions
  • EnableIntrospection defaults to false; MapCoreExGraphQLLite is anonymous by default — pass RequireAuthorization() explicitly if the host's REST endpoints are secured
  • Record enablement in the host's AGENTS.md "This Host's Feature Configuration" section as a plain **GraphQL:** Enabled (roots: ...) line — no dotnet new template symbol; this is a per-host hand-authored fact added as a side effect of this skill
  • Use args.GetIdentifier<TId>(name = "id") inside an AddGet<T> resolver to validate the identifier argument's presence, converting it to TId via TId.Parse where the boxed argument value isn't already an exact match (e.g. a variable-supplied Int arrives boxed as long, not int) — it throws an ArgumentException (mapped to ARGUMENT_ERROR) if missing/empty/not convertible to TId. Do not reach for args.TryGetValue(...) directly — GraphQLLiteArgs is not a dictionary; use args.Arguments.TryGetValue(...) only for non-identifier arguments.
  • The TItem/TId generics in AddQuery<TItem>/AddGet<TItem> are just whatever the entity's existing read-service method already returns (e.g. ProductLite, or the plain contract if there's no separate "Lite" projection) — there is no required naming convention; "Lite" in the samples is that domain's own projection name, not a CoreEx requirement.
  • CoreEx.Data.GraphQL is preview-versioned, but the code samples in this skill (AddQuery, AddGet, AddReferenceDataQueries, GetIdentifier, MapCoreExGraphQLLite, AddCoreExGraphQLLite, WithCoreExGraphQLTelemetry) are verified against the real source and kept current — copy them as-is and just build. Do not pre-emptively reflect on the installed .dll "to be safe" before even attempting a build; that's wasted work when the sample already matches. Only fall back to inspecting the installed package (per the resolution order in `coreex-conventions.instructions.md#when-unsure-of-a-coreex-api-member`) if an actual compile error appears after copying the sample.

For full workflow and code examples see `references/workflow.md`.

Key References

Categories