Rustfmt and write ARCHITECTURE.md
This commit is contained in:
parent
635a1a5ed7
commit
b871be2731
|
@ -0,0 +1,42 @@
|
|||
# async-graphql Architecture
|
||||
|
||||
This document describes the internal architecture of `async-graphql`, and can be useful to
|
||||
people wanting to contribute.
|
||||
|
||||
## Schema
|
||||
|
||||
When you create a schema, the first thing it does it asks the query, mutation and subscription types
|
||||
to register themselves in the schema's list of GraphQL types called the **registry**. Those types
|
||||
will then recursively register all the types that they depend on in the registry, and so on until
|
||||
every single type that is used has been registered in the registry.
|
||||
|
||||
## Query Execution
|
||||
|
||||
First of all, `async-graphql` will use the `async-graphql-parser` crate (located in the `parser/`
|
||||
directory) to parse the request document source. This also performs some necessary validations
|
||||
such as making sure that operation (i.e. query/mutation/subscription) names are unique and that the
|
||||
query does not contain an anonymous operation as well as a named one.
|
||||
|
||||
It then will validate the document as per the rest of GraphQL's validation rules. The `validation/`
|
||||
module handles this, and it works by walking through the entire document once and notifying the
|
||||
validation rules on the way to perform their validations and report errors if necessary. If
|
||||
`ValidationMode::Fast` is turned on, far far fewer rules are used.
|
||||
|
||||
Also at this stage some non-validators use the same architecture, such as the query depth calculator
|
||||
which keeps track of how deeply nested the query gets as the document is walked through.
|
||||
|
||||
At this point all the unnecessary operations (ones not selected by `operationName`) are dropped, and
|
||||
we will execute just one.
|
||||
|
||||
At the core of all the resolver logic there are two traits: `InputValueType` and `OutputValueType`
|
||||
which represent a GraphQL input value and GraphQL output value respectively. `InputValueType` just
|
||||
requires conversions to and from `async_graphql::Value`. `OutputValueType` is an async trait with a
|
||||
single method, `resolve`, which takes a field (e.g. `user(name: "sunli829") { display_name }`) and
|
||||
resolves it to a single value.
|
||||
|
||||
Scalars and enums are expected to ignore the input and serialize themselves, while objects,
|
||||
interfaces and unions are expected to read the selection set in the field and resolve and serialize
|
||||
each one of their fields.
|
||||
|
||||
As implementing `OutputValueType::resolve` manually quickly becomes very tedious helpful utilities
|
||||
are provided in the `resolver_utils` module and via macros.
|
|
@ -168,9 +168,9 @@ pub use validation::ValidationMode;
|
|||
|
||||
#[doc(no_inline)]
|
||||
pub use parser::{Pos, Positioned};
|
||||
pub use types::*;
|
||||
#[doc(no_inline)]
|
||||
pub use resolver_utils::{EnumType, ObjectType, ScalarType};
|
||||
pub use types::*;
|
||||
|
||||
/// Result type
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Value, InputValueResult};
|
||||
use crate::{InputValueResult, Value};
|
||||
|
||||
/// A GraphQL scalar.
|
||||
///
|
||||
|
|
Loading…
Reference in New Issue