A reference implementation for a bunch of GraphQL concerns using HotChocolate. Watch some videos!
Schema is implemented "schema first" for clear git diffs.
Each will be marked done ✅
Really the same as any .Net app https://chillicream.com/docs/hotchocolate/v13/security/authentication
Standard mechanisms: roles, policies https://chillicream.com/docs/hotchocolate/v13/security/authorization
Mechanisms to calculate and score query complexity. Would be implicitly applied to recursive graphs. https://chillicream.com/docs/hotchocolate/v13/security/operation-complexity
GraphQL has a formal spec as implemented by HotChocolate. On first read it is a little dense but upon understanding that the terms edge and node come from the world of graphs (duh!) it makes more sense. Only after a careful read of the whole design does the complexity of it make sense. A nicely written client like Strawberry Shake for .Net, Apollo's own client will hide all of this and make it friendly again. Most other languages have them as well.
That said, HotChocolate makes setting up paging dead simple. Just add the [UsePaging]
attribute and it runs. Notably an important statement is:
For the UsePaging middleware to work, our resolver needs to return an
IEnumerable<T> or an IQueryable<T>. The middleware will then apply
the pagination arguments to what we have returned. In the case of
an IQueryable<T> this means that the pagination operations can be
directly translated to native database queries.
Example usage where we ask for the next 2 companies after cursor "MQ==" (which
we received in endCursor
on a previous query).
{
companies(first: 2, after: "MQ==") {
edges {
cursor
node {
id
name
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
https://chillicream.com/docs/hotchocolate/v13/fetching-data/filtering
https://chillicream.com/docs/hotchocolate/v13/fetching-data/sorting
https://chillicream.com/docs/hotchocolate/v13/integrations
Projections incoming request to match database driver. https://chillicream.com/docs/hotchocolate/v13/fetching-data/projections
Data loading https://chillicream.com/docs/hotchocolate/v13/fetching-data/dataloader
The following use of unions would work well in many scenarios. Alterntatively there is the following approach to explore. TODO Explore https://youtu.be/wODiVDT8ECI
In the schema.graphql file see Company -> dynamicNotes: Notes
where union Notes = NotesA | NotesB
.
Unions let a sub node be one
of a list of understood schemas. Removing handling or a particular notes type will
result in an empty hash when encountered.
Example query:
{
companies {
id
name
dynamicNotes {
... on NotesA {
text
}
... on NotesB {
thoughts
imageUrl
}
}
}
}
https://chillicream.com/docs/hotchocolate/v13/server/instrumentation
Versioning handled by careful and slow deprecation before removal.
See the use of the @deprecated
directive
as demonstrated on the Company -> nickname
field and the findCompanies
query.
https://chillicream.com/docs/hotchocolate/v13/integrations/mongodb
https://chillicream.com/docs/hotchocolate/v13/defining-a-schema/mutations/
{
"id": int,
"name": string,
// Deprecated
"nickname": string
// Exercises authorization, sorting, pagination, filtering, n+1 data fetching
"employees": [
"name": string,
"phone": string,
"homeAddress":, { // Exercises load limiting / scoring and limiting high cost fetching
"street": string,
"number": string
}
],
// Exercises jagged schema / unions
"dynamicNotes": {
...
}
}