Add GraphQL handlers and add GraphQL schema
Remove all REST and JSON related handlers and error catchers.
This commit is contained in:
parent
5e24738bba
commit
26c86fe03e
|
@ -12,12 +12,3 @@ pub fn not_found() -> JsonValue {
|
|||
"reason": "Resource was not found",
|
||||
})
|
||||
}
|
||||
|
||||
/// Catches an HTTP 422 (Unprocessable Entity) error.
|
||||
#[catch(422)]
|
||||
pub fn unprocessable_entity() -> JsonValue {
|
||||
json!({
|
||||
"status": "error",
|
||||
"reason": "Could not parse JSON body or fields were missing",
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
use crate::models::{
|
||||
CompanyInfo, Customer, Invoice, NewCustomer, NewInvoice, NewTimeEntry, TimeEntry,
|
||||
};
|
||||
use crate::DbConn;
|
||||
|
||||
use diesel::prelude::*;
|
||||
use juniper::{object, Context, FieldResult, RootNode};
|
||||
|
||||
impl Context for DbConn {}
|
||||
|
||||
pub type Schema = RootNode<'static, Query, Mutation>;
|
||||
|
||||
/// The query root.
|
||||
pub struct Query;
|
||||
|
||||
#[object(Context = DbConn)]
|
||||
impl Query {
|
||||
/// Returns the current API version.
|
||||
fn api_version() -> &'static str {
|
||||
"1.0"
|
||||
}
|
||||
|
||||
/// Returns the company info with the given ID.
|
||||
fn company_info(context: &DbConn, id: i32) -> FieldResult<CompanyInfo> {
|
||||
retrieve!(CompanyInfo, id, **context).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Returns all known customers.
|
||||
fn customers(context: &DbConn) -> FieldResult<Vec<Customer>> {
|
||||
all!(Customer, **context).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Returns the customer with the given ID.
|
||||
fn customer(context: &DbConn, id: i32) -> FieldResult<Customer> {
|
||||
retrieve!(Customer, id, **context).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Returns all known customers.
|
||||
fn customers(context: &DbConn) -> FieldResult<Vec<Customer>> {
|
||||
all!(Customer, **context).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Returns the customer with the given ID.
|
||||
fn invoice(context: &DbConn, id: i32) -> FieldResult<Invoice> {
|
||||
retrieve!(Invoice, id, **context).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Returns all known invoices.
|
||||
fn invoices(context: &DbConn) -> FieldResult<Vec<Invoice>> {
|
||||
all!(Invoice, **context).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Returns the time entry with the given ID.
|
||||
fn time_entry(context: &DbConn, id: i32) -> FieldResult<TimeEntry> {
|
||||
retrieve!(TimeEntry, id, **context).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Returns all known invoices.
|
||||
fn time_entries(context: &DbConn) -> FieldResult<Vec<TimeEntry>> {
|
||||
all!(TimeEntry, **context).map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
/// The mutation root.
|
||||
pub struct Mutation;
|
||||
|
||||
#[object(Context = DbConn)]
|
||||
impl Mutation {
|
||||
/// Returns the current API version.
|
||||
fn api_version() -> &'static str {
|
||||
"1.0"
|
||||
}
|
||||
|
||||
/// Creates a new customer.
|
||||
fn create_customer(context: &DbConn, new_customer: NewCustomer) -> FieldResult<Customer> {
|
||||
create!(Customer, new_customer, **context).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Creates a new invoice.
|
||||
fn create_invoice(context: &DbConn, new_invoice: NewInvoice) -> FieldResult<Invoice> {
|
||||
create!(Invoice, new_invoice, **context).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Creates a new time entry.
|
||||
fn create_time_entry(context: &DbConn, new_time_entry: NewTimeEntry) -> FieldResult<TimeEntry> {
|
||||
create!(TimeEntry, new_time_entry, **context).map_err(Into::into)
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ use rocket::get;
|
|||
|
||||
pub mod company;
|
||||
pub mod customers;
|
||||
pub mod graphql;
|
||||
pub mod invoices;
|
||||
pub mod timeline;
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
//! The GraphQL handlers
|
||||
//!
|
||||
//! Handlers for querying and mutating models via GraphQL.
|
||||
|
||||
use crate::graphql::Schema;
|
||||
use crate::DbConn;
|
||||
|
||||
use juniper_rocket::{graphiql_source, playground_source, GraphQLRequest, GraphQLResponse};
|
||||
use rocket::response::content::Html;
|
||||
use rocket::{get, post, State};
|
||||
|
||||
#[get("/graphiql")]
|
||||
pub fn graphiql() -> Html<String> {
|
||||
graphiql_source("/graphql")
|
||||
}
|
||||
|
||||
#[get("/playground")]
|
||||
pub fn playground() -> Html<String> {
|
||||
playground_source("/graphql")
|
||||
}
|
||||
|
||||
#[get("/?<request>")]
|
||||
pub fn get(request: GraphQLRequest, conn: DbConn, schema: State<Schema>) -> GraphQLResponse {
|
||||
request.execute(&schema, &conn)
|
||||
}
|
||||
|
||||
#[post("/", data = "<request>")]
|
||||
pub fn post(request: GraphQLRequest, conn: DbConn, schema: State<Schema>) -> GraphQLResponse {
|
||||
request.execute(&schema, &conn)
|
||||
}
|
46
src/main.rs
46
src/main.rs
|
@ -15,7 +15,10 @@ use rocket_contrib::serve::StaticFiles;
|
|||
pub mod helpers;
|
||||
|
||||
pub mod catchers;
|
||||
pub mod graphql;
|
||||
pub mod handlers;
|
||||
pub mod models;
|
||||
pub mod schema;
|
||||
|
||||
// This macro from `diesel_migrations` defines an `embedded_migrations` module containing a
|
||||
// function named `run`. This allows the example to be run and tested without any outside setup of
|
||||
|
@ -45,48 +48,19 @@ fn rocket() -> Rocket {
|
|||
rocket::ignite()
|
||||
.attach(DbConn::fairing())
|
||||
.attach(AdHoc::on_attach("Database Migrations", run_db_migrations))
|
||||
.manage(graphql::Schema::new(graphql::Query, graphql::Mutation))
|
||||
.mount("/", routes![handlers::index])
|
||||
.mount(
|
||||
"/company",
|
||||
routes![handlers::company::index, handlers::company::create],
|
||||
)
|
||||
.mount(
|
||||
"/customers",
|
||||
"/graphql",
|
||||
routes![
|
||||
handlers::customers::index,
|
||||
handlers::customers::create,
|
||||
handlers::customers::new,
|
||||
handlers::customers::show,
|
||||
handlers::customers::update,
|
||||
handlers::customers::destroy,
|
||||
handlers::customers::invoices::create,
|
||||
handlers::customers::invoices::new,
|
||||
handlers::customers::invoices::show,
|
||||
handlers::customers::invoices::update,
|
||||
handlers::customers::tasks::create,
|
||||
handlers::customers::tasks::new,
|
||||
handlers::customers::tasks::show,
|
||||
handlers::customers::tasks::update,
|
||||
handlers::customers::tasks::destroy,
|
||||
handlers::graphql::playground,
|
||||
handlers::graphql::graphiql,
|
||||
handlers::graphql::get,
|
||||
handlers::graphql::post,
|
||||
],
|
||||
)
|
||||
.mount("/invoices", routes![handlers::invoices::index])
|
||||
.mount("/static", static_files)
|
||||
.mount(
|
||||
"/timeline",
|
||||
routes![
|
||||
handlers::timeline::index,
|
||||
handlers::timeline::create,
|
||||
handlers::timeline::new,
|
||||
handlers::timeline::show,
|
||||
handlers::timeline::update,
|
||||
handlers::timeline::destroy,
|
||||
],
|
||||
)
|
||||
.register(catchers![
|
||||
catchers::not_found,
|
||||
catchers::unprocessable_entity
|
||||
])
|
||||
.register(catchers![catchers::not_found])
|
||||
}
|
||||
|
||||
/// Runs the Rocket application.
|
||||
|
|
Loading…
Reference in New Issue