Update async-graphql-tide 2

This commit is contained in:
Sunli 2021-11-12 07:45:49 +08:00
parent acb44bdd05
commit 098255cce7
3 changed files with 58 additions and 57 deletions

View File

@ -23,49 +23,24 @@ use tide::{
};
#[cfg(feature = "websocket")]
pub use subscription::SubscriptionBuilder;
pub use subscription::GraphQLSubscriptionBuilder;
/// Create a new GraphQL endpoint with the schema.
///
/// Default multipart options are used and batch operations are supported.
pub fn endpoint<Query, Mutation, Subscription>(
schema: Schema<Query, Mutation, Subscription>,
) -> Endpoint<Query, Mutation, Subscription> {
Endpoint {
schema,
opts: MultipartOptions::default(),
batch: true,
}
}
/// A GraphQL endpoint.
/// An endpoint for GraphQL.
///
/// This is created with the [`endpoint`](fn.endpoint.html) function.
#[non_exhaustive]
pub struct Endpoint<Query, Mutation, Subscription> {
pub struct GraphQLEndpoint<Query, Mutation, Subscription> {
/// The schema of the endpoint.
pub schema: Schema<Query, Mutation, Subscription>,
/// The multipart options of the endpoint.
pub opts: MultipartOptions,
/// Whether to support batch requests in the endpoint.
pub batch: bool,
}
schema: Schema<Query, Mutation, Subscription>,
impl<Query, Mutation, Subscription> Endpoint<Query, Mutation, Subscription> {
/// Set the multipart options of the endpoint.
#[must_use]
pub fn multipart_opts(self, opts: MultipartOptions) -> Self {
Self { opts, ..self }
}
/// Set whether batch requests are supported in the endpoint.
#[must_use]
pub fn batch(self, batch: bool) -> Self {
Self { batch, ..self }
}
/// The multipart options of the endpoint.
opts: MultipartOptions,
/// Whether to support batch requests in the endpoint.
batch: bool,
}
// Manual impl to remove bounds on generics
impl<Query, Mutation, Subscription> Clone for Endpoint<Query, Mutation, Subscription> {
impl<Query, Mutation, Subscription> Clone for GraphQLEndpoint<Query, Mutation, Subscription> {
fn clone(&self) -> Self {
Self {
schema: self.schema.clone(),
@ -75,9 +50,34 @@ impl<Query, Mutation, Subscription> Clone for Endpoint<Query, Mutation, Subscrip
}
}
impl<Query, Mutation, Subscription> GraphQLEndpoint<Query, Mutation, Subscription> {
/// Create a new GraphQL endpoint with the schema.
pub fn new(schema: Schema<Query, Mutation, Subscription>) -> Self {
GraphQLEndpoint {
schema,
opts: MultipartOptions::default(),
batch: true,
}
}
/// Set the multipart options of the endpoint.
#[must_use]
pub fn multipart_opts(self, opts: MultipartOptions) -> Self {
Self { opts, ..self }
}
/// Set whether batch requests are supported in the endpoint.
///
/// Default is `true`.
#[must_use]
pub fn batch(self, batch: bool) -> Self {
Self { batch, ..self }
}
}
#[async_trait]
impl<Query, Mutation, Subscription, TideState> tide::Endpoint<TideState>
for Endpoint<Query, Mutation, Subscription>
for GraphQLEndpoint<Query, Mutation, Subscription>
where
Query: ObjectType + 'static,
Mutation: ObjectType + 'static,

View File

@ -1,13 +1,12 @@
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::str::FromStr;
use async_graphql::http::{WebSocket as AGWebSocket, WebSocketProtocols, WsMessage};
use async_graphql::{Data, ObjectType, Result, Schema, SubscriptionType};
use futures_util::future::Ready;
use futures_util::{future, StreamExt};
use tide::{Endpoint, Request, Response, StatusCode};
use tide::{Endpoint, Request, StatusCode};
use tide_websockets::Message;
type DefaultOnConnCreateType<S> = fn(&Request<S>) -> Ready<Result<Data>>;
@ -24,20 +23,20 @@ fn default_on_connection_init(_: serde_json::Value) -> Ready<Result<Data>> {
/// GraphQL subscription builder.
#[cfg_attr(docsrs, doc(cfg(feature = "websocket")))]
pub struct SubscriptionBuilder<S, Query, Mutation, Subscription, OnCreate, OnInit> {
pub struct GraphQLSubscriptionBuilder<TideState, Query, Mutation, Subscription, OnCreate, OnInit> {
schema: Schema<Query, Mutation, Subscription>,
on_connection_create: OnCreate,
on_connection_init: OnInit,
_mark: PhantomData<S>,
_mark: PhantomData<TideState>,
}
impl<S, Query, Mutation, Subscription>
SubscriptionBuilder<
S,
impl<TideState, Query, Mutation, Subscription>
GraphQLSubscriptionBuilder<
TideState,
Query,
Mutation,
Subscription,
DefaultOnConnCreateType<S>,
DefaultOnConnCreateType<TideState>,
DefaultOnConnInitType,
>
{
@ -53,7 +52,7 @@ impl<S, Query, Mutation, Subscription>
}
impl<S, Query, Mutation, Subscription, OnCreate, OnInit>
SubscriptionBuilder<S, Query, Mutation, Subscription, OnCreate, OnInit>
GraphQLSubscriptionBuilder<S, Query, Mutation, Subscription, OnCreate, OnInit>
{
/// Specify the callback function to be called when the connection is created.
///
@ -61,12 +60,12 @@ impl<S, Query, Mutation, Subscription, OnCreate, OnInit>
pub fn on_connection_create<OnCreate2, Fut>(
self,
callback: OnCreate2,
) -> SubscriptionBuilder<S, Query, Mutation, Subscription, OnCreate2, OnInit>
) -> GraphQLSubscriptionBuilder<S, Query, Mutation, Subscription, OnCreate2, OnInit>
where
OnCreate2: Fn(&Request<S>) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<Data>> + Send + 'static,
{
SubscriptionBuilder {
GraphQLSubscriptionBuilder {
schema: self.schema,
on_connection_create: callback,
on_connection_init: self.on_connection_init,
@ -80,12 +79,12 @@ impl<S, Query, Mutation, Subscription, OnCreate, OnInit>
pub fn on_connection_init<OnInit2, Fut>(
self,
callback: OnInit2,
) -> SubscriptionBuilder<S, Query, Mutation, Subscription, OnCreate, OnInit2>
) -> GraphQLSubscriptionBuilder<S, Query, Mutation, Subscription, OnCreate, OnInit2>
where
OnInit2: FnOnce(serde_json::Value) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<Data>> + Send + 'static,
{
SubscriptionBuilder {
GraphQLSubscriptionBuilder {
schema: self.schema,
on_connection_create: self.on_connection_create,
on_connection_init: callback,
@ -94,20 +93,21 @@ impl<S, Query, Mutation, Subscription, OnCreate, OnInit>
}
}
impl<S, Query, Mutation, Subscription, OnCreate, OnCreateFut, OnInit, OnInitFut>
SubscriptionBuilder<S, Query, Mutation, Subscription, OnCreate, OnInit>
impl<TideState, Query, Mutation, Subscription, OnCreate, OnCreateFut, OnInit, OnInitFut>
GraphQLSubscriptionBuilder<TideState, Query, Mutation, Subscription, OnCreate, OnInit>
where
S: Send + Sync + Clone + 'static,
TideState: Send + Sync + Clone + 'static,
Query: ObjectType + 'static,
Mutation: ObjectType + 'static,
Subscription: SubscriptionType + 'static,
OnCreate: Fn(&Request<S>) -> OnCreateFut + Send + Clone + Sync + 'static,
OnCreate: Fn(&Request<TideState>) -> OnCreateFut + Send + Clone + Sync + 'static,
OnCreateFut: Future<Output = async_graphql::Result<Data>> + Send + 'static,
OnInit: FnOnce(serde_json::Value) -> OnInitFut + Clone + Send + Sync + 'static,
OnInitFut: Future<Output = async_graphql::Result<Data>> + Send + 'static,
{
pub fn build(self) -> impl Endpoint<S> {
tide_websockets::WebSocket::<S, _>::new(move |request, connection| {
/// Create an endpoint for graphql subscription.
pub fn build(self) -> impl Endpoint<TideState> {
tide_websockets::WebSocket::<TideState, _>::new(move |request, connection| {
let schema = self.schema.clone();
let on_connection_create = self.on_connection_create.clone();
let on_connection_init = self.on_connection_init.clone();

View File

@ -3,6 +3,7 @@ mod test_utils;
use std::io::Read;
use async_graphql::*;
use async_graphql_tide::GraphQLEndpoint;
use reqwest::{header, StatusCode};
use serde_json::json;
@ -25,7 +26,7 @@ async fn quickstart() -> Result<()> {
let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription).finish();
let mut app = tide::new();
let endpoint = async_graphql_tide::endpoint(schema);
let endpoint = GraphQLEndpoint::new(schema);
app.at("/").post(endpoint.clone()).get(endpoint);
app.listen(listen_addr).await
});
@ -184,7 +185,7 @@ async fn upload() -> Result<()> {
let schema = Schema::build(QueryRoot, MutationRoot, EmptySubscription).finish();
let mut app = tide::new();
app.at("/").post(async_graphql_tide::endpoint(schema));
app.at("/").post(GraphQLEndpoint::new(schema));
app.listen(listen_addr).await
});