Crate cynic

Source
Expand description

§Cynic

Cynic is a GraphQL query builder & data mapper for Rust.

This documentation is primarily intended to be a reference for specific functions, for a guide to using Cynic see the website: cynic-rs.dev.

§Overview

To get started with Cynic you’ll need a GraphQL schema for the API you wish to query. The examples will be using the star wars API.

§Generating a Query DSL

Once you’ve got your schema installed locally, you’ll need to use the use_schema macro to generate a schema module:

mod schema {
    cynic::use_schema!("../schemas/starwars.schema.graphql");
}

This macro generates a few things:

  1. Some structs to represent the Input types the underlying schema. You may need to use these to build mutations or as parameters to queries.
  2. Definitions of all the Enums in the provided schema. You’ll need these if you want to use any enum types.
  3. Type safe selection set functions. These can be used to build up a query manually, though it’s usually easier to use the QueryFragment derive functionality explained below. Hopefully you’ll not need to use these directly too often.

Though using macros to generate these is convenient, it does leave a lot of code to the imagination. You can get a glimpse of the things this defines by running cargo doc --document-private-items and having a look in the schema module. It’s not ideal, but at least provides some visibility into the various enum types.

§Creating QueryFragments

Now that you have a schema defined, you can start building some queries. Cynic lets you do this by deriving QueryFragment for a struct. For example, if we wanted to know what director title & director a Star Wars film had, we could define this QueryFragment:


#[derive(cynic::QueryFragment)]
#[cynic(schema_path = "../schemas/starwars.schema.graphql")]
struct Film {
    title: Option<String>,
    director: Option<String>,
}

// This `Film` struct can now be used as the type of a field on any other
// `QueryFragment` struct and cynic will know how to turn that into a GraphQL
// query, and populate the `Film` struct from the response.

// For example, if we wanted to know the Director for a particular film:

#[derive(cynic::QueryFragment)]
#[cynic(
    schema_path = "../schemas/starwars.schema.graphql",
    graphql_type = "Root"
)]
struct FilmDirectorQuery {
    // Here we use the `#[arguments()]` attribute on the `film` field to provide a
    // hard coded film ID to look up.  Though useful for demonstration, hard coded
    // arguments like this aren't much use in reality.  For more details on providing
    // runtime arguments please see below.
    #[arguments(id = cynic::Id::new("ZmlsbXM6MQ=="))]
    film: Option<Film>,
}

// You can then build a `cynic::Operation` from this fragment
use cynic::QueryBuilder;
let operation = FilmDirectorQuery::build(());

operation above implements serde::Serialize so can be used with any HTTP client. A selection of HTTP client integrations are provided in cynic::http - see the docs there for examples of using a cynic::Operation

let response = reqwest::blocking::Client::new()
                    .post("a_url")
                    .json(&operation)
                    .send()?;
let result = response.json::<GraphQlResponse<FilmDirectorQuery>>()?;

After this code has run, result will be an instance of GraphQlResponse<FilmDirectorQuery> with the film populated appropriately.

§Dynamic Query Arguments

The query above was useful for demonstration, but you’ll usually want to be able to provide parameters to your query. To do this, you should define a struct that contains all of the parameters you want to provide:


// Deriving `QueryVariables` allows this struct to be used as variables in a
// `QueryFragment`, whether it represents part of a query or a whole query.
#[derive(cynic::QueryVariables)]
struct FilmArguments {
    id: Option<cynic::Id>,
}

// You can now define a query to use these arguments on.  For example, to make
// `FilmDirectorQuery` a bit more dynamic:
#[derive(cynic::QueryFragment)]
#[cynic(
    schema_path = "../schemas/starwars.schema.graphql",
    graphql_type = "Root",
    // By adding the `variables` parameter to our `QueryFragment` we've made a variable
    // named `args` available for use in the `arguments` attribute.
    variables = "FilmArguments"
)]
struct FilmDirectorQueryWithArgs {
    // Here we use `args`, which we've declared above to be an instance of `FilmArguments`
    #[arguments(id: $id)]
    film: Option<Film>,
}

// Then we can build a query using this new struct;
use cynic::QueryBuilder;
let operation = FilmDirectorQueryWithArgs::build(FilmArguments {
    id: Some("ZmlsbXM6MQ==".into()),
});

§Feature Flags

Cynic has a few features that are controlled by feature flags.

  • http-surf adds integration with the surf http client.
  • http-reqwest adds async integration with the reqwest http client.
  • http-reqwest-blocking adds blocking integration with the reqwest http client.
  • rkyv can be used to speed up compiles when working with large schemas.

It’s worth noting that each of these features pulls in extra dependencies, which may impact your build size. Particularly if you’re targeting WASM. In particular the url crate has known issues when targeting web assembly.

Re-exports§

pub use variables::QueryVariableLiterals;
pub use variables::QueryVariables;
pub use variables::QueryVariablesFields;
pub use serde;

Modules§

coercions
Tools for enforcing the GraphQL coercion rules
http
HTTP client support for cynic.
queries
Tools for building GraphQL queries in cynic
schema
Traits for describing a GraphQL schema in Rust.
variables
Types & traits for working with GraphQL Variables

Macros§

assert_impl
Asserts that the type implements all of the given traits.
assert_type_eq_all
Asserts that all types in a list are equal to each other.
impl_coercions
Implements the default GraphQL list & option coercion rules for a type.
impl_scalar
Implements a set of scalar traits for the given type & type lock.
use_schema
Imports a schema for use by cynic.

Structs§

GraphQlError
A model describing an error which has taken place during execution.
GraphQlErrorLocation
A line and column offset describing the location of an error within a GraphQL document.
GraphQlResponse
The response to a GraphQl operation
Id
A GraphQL ID
Operation
An Operation that can be sent to a remote GraphQL server.
OperationBuilder
Low level builder for Operation.
StreamingOperation
A StreamingOperation is an Operation that expects a stream of results.

Enums§

GraphQlErrorPathSegment
A segment of a GraphQL error path.
OperationBuildError
Errors that can occur when building the operation

Traits§

Enum
A GraphQL Enum.
InlineFragments
A QueryFragment that contains a set of inline fragments
InputObject
A GraphQL input object.
MutationBuilder
Provides a build function on QueryFragments that represent a mutation
QueryBuilder
Provides a build function on QueryFragments that represent a query
QueryFragment
A trait that marks a type as part of a GraphQL query.
SubscriptionBuilder
Provides a build function on QueryFragments that represent a subscription

Attribute Macros§

schema
Imports a registered schema into a schema module.
schema_for_derives
An attribute macro to automatically add schema attributes to cynic derives.

Derive Macros§

Enum
Derives cynic::Enum
InlineFragments
Derives cynic::InlineFragments
InputObject
Derives InputObject
QueryFragment
Derives cynic::QueryFragment
QueryVariableLiterals
Derives cynic::QueryVariableLiterals
QueryVariables
Derives cynic::QueryVariables
Scalar
Derives cynic::Scalar