All Projects → graphql-rust → Graphql Client

graphql-rust / Graphql Client

Licence: other
Typed, correct GraphQL requests and responses in Rust

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to Graphql Client

Graphql
Package graphql provides a GraphQL client implementation.
Stars: ✭ 467 (-24.68%)
Mutual labels:  graphql, client
Uno
Build Mobile, Desktop and WebAssembly apps with C# and XAML. Today. Open source and professionally supported.
Stars: ✭ 6,029 (+872.42%)
Mutual labels:  webassembly, wasm
Wasm And Rust
WebAssembly and Rust: A Web Love Story
Stars: ✭ 476 (-23.23%)
Mutual labels:  webassembly, wasm
Jwebassembly
Java bytecode to WebAssembly compiler
Stars: ✭ 426 (-31.29%)
Mutual labels:  webassembly, wasm
Wasmtime
Standalone JIT-style runtime for WebAssembly, using Cranelift
Stars: ✭ 6,413 (+934.35%)
Mutual labels:  webassembly, wasm
Camaro
camaro is an utility to transform XML to JSON, using Node.js binding to native XML parser pugixml, one of the fastest XML parser around.
Stars: ✭ 438 (-29.35%)
Mutual labels:  webassembly, wasm
Awesome Wasm Runtimes
A list of webassemby runtimes
Stars: ✭ 490 (-20.97%)
Mutual labels:  webassembly, wasm
Rustynes
👾 An NES emulator by Rust and WebAssembly
Stars: ✭ 399 (-35.65%)
Mutual labels:  webassembly, wasm
Wasm Loader
✨ WASM webpack loader
Stars: ✭ 604 (-2.58%)
Mutual labels:  webassembly, wasm
Vim.wasm
Vim editor ported to WebAssembly
Stars: ✭ 4,915 (+692.74%)
Mutual labels:  webassembly, wasm
Graphql Client
A GraphQL Client for .NET Standard
Stars: ✭ 418 (-32.58%)
Mutual labels:  graphql, client
Webassemblyjs
Toolchain for WebAssembly
Stars: ✭ 566 (-8.71%)
Mutual labels:  webassembly, wasm
Ink
Parity's ink! to write smart contracts
Stars: ✭ 407 (-34.35%)
Mutual labels:  webassembly, wasm
Asmble
Compile WebAssembly to JVM and other WASM tools
Stars: ✭ 466 (-24.84%)
Mutual labels:  webassembly, wasm
Bootstrapblazor
A set of enterprise-class UI components based on Bootstrap and Blazor
Stars: ✭ 403 (-35%)
Mutual labels:  webassembly, wasm
Genact
🌀 A nonsense activity generator
Stars: ✭ 5,109 (+724.03%)
Mutual labels:  webassembly, wasm
Lucet
Lucet, the Sandboxing WebAssembly Compiler.
Stars: ✭ 4,006 (+546.13%)
Mutual labels:  webassembly, wasm
Graphql Ws
Coherent, zero-dependency, lazy, simple, GraphQL over WebSocket Protocol compliant server and client.
Stars: ✭ 398 (-35.81%)
Mutual labels:  graphql, client
Zwitterion
A web dev server that lets you import anything*
Stars: ✭ 514 (-17.1%)
Mutual labels:  webassembly, wasm
Dotnet Webassembly
Create, read, modify, write and execute WebAssembly (WASM) files from .NET-based applications.
Stars: ✭ 535 (-13.71%)
Mutual labels:  webassembly, wasm

graphql_client

Github actions Status docs crates.io Join the chat

A typed GraphQL client library for Rust.

Features

  • Precise types for query variables and responses.
  • Supports GraphQL fragments, objects, unions, inputs, enums, custom scalars and input objects.
  • Works in the browser (WebAssembly).
  • Subscriptions support (serialization-deserialization only at the moment).
  • Copies documentation from the GraphQL schema to the generated Rust code.
  • Arbitrary derives on the generated responses.
  • Arbitrary custom scalars.
  • Supports multiple operations per query document.
  • Supports setting GraphQL fields as deprecated and having the Rust compiler check their use.
  • web client for boilerplate-free API calls from browsers.

Getting started

  • If you are not familiar with GraphQL, the official website provides a very good and comprehensive introduction.

  • Once you have written your query (most likely in something like graphiql), save it in a .graphql file in your project.

  • In order to provide precise types for a response, graphql_client needs to read the query and the schema at compile-time.

    To download the schema, you have multiple options. This projects provides a CLI, however it does not matter what tool you use, the resulting schema.json is the same.

  • We now have everything we need to derive Rust types for our query. This is achieved through a procedural macro, as in the following snippet:

    use graphql_client::GraphQLQuery;
    
    // The paths are relative to the directory where your `Cargo.toml` is located.
    // Both json and the GraphQL schema language are supported as sources for the schema
    #[derive(GraphQLQuery)]
    #[graphql(
        schema_path = "tests/unions/union_schema.graphql",
        query_path = "tests/unions/union_query.graphql",
    )]
    pub struct UnionQuery;
    

    The derive will generate a module named union_query in this example - the name is the struct's name, but in snake case.

    That module contains all the struct and enum definitions necessary to deserialize a response to that query.

    The root type for the response is named ResponseData. The GraphQL response will take the form of a Response<ResponseData> (the Response type is always the same).

    The module also contains a struct called Variables representing the variables expected by the query.

  • We now need to create the complete payload that we are going to send to the server. For convenience, the GraphQLQuery trait, is implemented for the struct under derive, so a complete query body can be created this way:

    use graphql_client::{GraphQLQuery, Response};
    use std::error::Error;
    use reqwest;
    
    #[derive(GraphQLQuery)]
    #[graphql(
        schema_path = "tests/unions/union_schema.graphql",
        query_path = "tests/unions/union_query.graphql",
        response_derives = "Debug",
    )]
    pub struct UnionQuery;
    
    async fn perform_my_query(variables: union_query::Variables) -> Result<(), Box<dyn Error>> {
    
        // this is the important line
        let request_body = UnionQuery::build_query(variables);
    
        let client = reqwest::Client::new();
        let mut res = client.post("/graphql").json(&request_body).send().await?;
        let response_body: Response<union_query::ResponseData> = res.json().await?;
        println!("{:#?}", response_body);
        Ok(())
    }
    

A complete example using the GitHub GraphQL API is available, as well as sample rustdoc output.

Deriving specific traits on the response

The generated response types always derive serde::Deserialize but you may want to print them (Debug), compare them (PartialEq) or derive any other trait on it. You can achieve this with the response_derives option of the graphql attribute. Example:

use graphql_client::GraphQLQuery;

#[derive(GraphQLQuery)]
#[graphql(
    schema_path = "tests/unions/union_schema.graphql",
    query_path = "tests/unions/union_query.graphql",
    response_derives = "Serialize,PartialEq",
)]
struct UnionQuery;

Custom scalars

The generated code will reference the scalar types as defined in the server schema. This means you have to provide matching rust types in the scope of the struct under derive. It can be as simple as declarations like type Email = String;. This gives you complete freedom on how to treat custom scalars, as long as they can be deserialized.

Deprecations

The generated code has support for @deprecated field annotations. You can configure how deprecations are handled via the deprecated argument in the GraphQLQuery derive:

use graphql_client::GraphQLQuery;

#[derive(GraphQLQuery)]
#[graphql(
  schema_path = "tests/unions/union_schema.graphql",
  query_path = "tests/unions/union_query.graphql",
  deprecated = "warn"
)]
pub struct UnionQuery;

Valid values are:

  • allow: the response struct fields are not marked as deprecated.
  • warn: the response struct fields are marked as #[deprecated].
  • deny: The struct fields are not included in the response struct and using them is a compile error.

The default is warn.

Query documents with multiple operations

You can write multiple operations in one query document (one .graphql file). You can then select one by naming the struct you #[derive(GraphQLQuery)] on with the same name as one of the operations. This is neat, as it allows sharing fragments between operations.

Note that the struct and the operation in the GraphQL file must have the same name. We enforce this to make the generated code more predictable.

use graphql_client::GraphQLQuery;

#[derive(GraphQLQuery)]
#[graphql(
    schema_path = "tests/unions/union_schema.graphql",
    query_path = "tests/unions/union_query.graphql",
)]
pub struct UnionQuery;

There is an example in the tests.

Documentation for the generated modules

You can use cargo doc --document-private-items to generate rustdoc documentation on the generated code.

Make cargo recompile when .graphql files have changed

There is an include option you can add to your Cargo.toml. It currently has issues however (see this issue).

Examples

See the examples directory in this repository.

Contributors

Warmest thanks to all those who contributed in any way (not only code) to this project:

Code of conduct

Anyone who interacts with this project in any space, including but not limited to this GitHub repository, must follow our code of conduct.

License

Licensed under either of these:

Contributing

Unless you explicitly state otherwise, any contribution you intentionally submit for inclusion in the work, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].