Last updated:
0 purchases
leto shelf
Leto Shelf #
Leto GraphQL web server bindings and utilities for shelf.
Table of Contents #
Quickstart
Install
Server example
Handlers
graphQLHttp
graphQLWebSocket
Web UI Explorers
GraphiQL
Playground
Altair
Features and Utilities
File Upload
Requests and Responses
Request
Headers
Custom Response
Middlewares
etag
cors
jsonParse
Quickstart #
For more general information and examples for building GraphQL schemas and servers using Leto, please see the main repository's https://github.com/juancastillo0/leto README. This README only contains information associated with bindings and utilities for building Leto powered web servers with shelf.
Most sections in this README have a "Tests" link. You can read the tests source code for usage examples.
Install #
Add dependencies to your pubspec.yaml
dependencies:
leto_schema: ^0.0.1-dev.3
leto: ^0.0.1-dev.1
leto_shelf: ^0.0.1-dev.1
shelf: ^1.0.0
shelf_router: ^1.0.0
# Not nessary for the server, just for testing it
http: ^1.0.0
dev_dependencies:
# Only if you use code generation
leto_generator: ^0.0.1-dev.3
copied to clipboard
Server example #
A fullstack Dart example with Flutter client and Leto/Shelf server can be found in https://github.com/juancastillo0/leto/tree/main/chat_example
Handlers #
This package provides shelf handlers for answering HTTP requests.
graphQLHttp #
Tests
Handles POST and GET requests for "application/graphql", "application/json", "application/graphql+json" and "multipart/form-data" mime types. The implementations follows the https://github.com/graphql/graphql-over-http/blob/main/spec/GraphQLOverHTTP.md and https://github.com/jaydenseric/graphql-multipart-request-spec specifications.
POST requests support GraphQL Query and Mutation operations
We restrict GET requests to allow only GraphQL Query operations
Support for file Upload with "multipart/form-data" bodies
A 200 status code with a JSON body will be sent by default, with a structure following the spec.
A 400 status code will be sent for requests that do not follow the specifications.
// TODO: A 400 status code will be sent for requests with validation errors.
A 405, method not allowed, status code will be sent for Mutation operations in GET requests
graphQLWebSocket #
Tests
Handles Query, Mutation and Subscription requests using the "graphql-ws" or "graphql-transport-ws" Web Socket subprotocols. When using this handler, the headers and response utilities will have no effect.
The validateIncomingConnection parameter allows you to support authentication for your Web Socket connection, it also passes a GraphQLWebSocketServer as an argument which could be used for closing the connection. Some ping and keep alive Duration configuration parameters are provided to remove stale connection or identify problems when reaching the client.
// TODO: 2A throwing in the subscribe field function
Web UI Explorers #
Tests
These web pages will allow you to explore your GraphQL Schema, view all the types and fields, read each element's documentation, and execute requests against a GraphQL server.
Usually exposed as static HTML in your deployed server. Each has multiple configurations for determining the default tabs, queries and variables, the GraphQL HTTP and WebSocket (subscription) endpoints, the UI's theme and more.
All of the static HTML files and configurations can be found in the graphql_ui folder.
GraphiQL #
Documentation. Use graphiqlHandler. The classic GraphQL explorer
Playground #
Documentation. Use playgroundHandler. Support for multiple tabs, subscriptions.
Altair #
Documentation. Use altairHandler. Support for file Upload, multiple tabs, subscriptions, plugins.
Features and Utilities #
Some useful utilities and bindings for working with shelf HTTP requests and responses in Leto.
File Upload #
Tests
Only available using "multipart/form-data" bodies, your HTTP client will need to follow the https://github.com/jaydenseric/graphql-multipart-request-spec specification. Can't we used with Web Sockets.
Use the Upload class and the Upload.graphQLType for building schemas. When using code generation Upload.graphQLType will be used with no additional configuration, you just need to put the Upload type as input to a resolver or as a field in an Input Object.
Requests and Responses #
Tests
Request #
You can access the shelf HTTP request using the extractRequest function or the Dart extension (provided in the same file) for Leto's field resolver Ctx argument.
import 'package:leto_schema/leto_schema.dart'; // Query and Ctx
import 'package:leto_shelf/leto_shelf.dart'; // extractRequest and ctx.request extension
@Query()
String getName(Ctx ctx) {
final Request request = ctx.request;
assert(request == extractRequest(ctx));
assert(request.headersAll is Map<String, List<String>>);
return '';
}
copied to clipboard
Headers #
appendHeader
Adds a new value to a given header, does not override the previously set values for the header.
changeHeader
Sets a new value to a given header, will override the previously set values for the header.
Custom Response #
updateResponse
If the new response contains a body or the status code is different from 200, the new response will be returned without modification. However, if the new response does not contain a body and it's status code is 200 (maybe you only changed the headers), the default GraphQL json body will be appended along side the "application/json" content type response header.
import 'package:leto_schema/leto_schema.dart';
import 'package:leto_shelf/leto_shelf.dart';
@Query()
String getName(Ctx ctx) {
ctx.appendHeader('custom-header', 'headers-value');
assert(extractResponse(ctx).headersAll['custom-header']![0] == 'headers-value');
ctx.changeHeader('custom-header', 'headers-value-2'); // override
updateResponse(ctx, (response) => response.change(
// Could also call `ctx.appendHeader` twice for each value
headers: {'custom-header2': ['h1', 'h2']}
));
final Response response = extractResponse(ctx);
assert(response.headersAll['custom-header']![0] == 'headers-value-2'); // overridden
assert(response.headersAll['custom-header2']![0] == 'h1');
assert(response.headersAll['custom-header2']![1] == 'h2');
return '';
}
copied to clipboard
Middlewares #
Other shelf middlewares not really specific to GraphQL servers.
etag #
Tests
ETag and If-None-Match headers computation and verification.
This middleware will compute an ETag for every response that returns true in the provided shouldProcessResponse function (default: response with a status code less than 300) and set it in the "ETag" response header. If an ETag was already set, it will leave it as is. With the ETag, it will compare it with the request's "If-None-Match" values. If the ETag is found, a 304 status code will be sent with the ETag in the response header.
You can specify a custom hasher function that returns the ETag given the response's body, by default we use package:crypt's sha256 encoder.
cors #
Tests
CORS requests configuration.
jsonParse #
Parse JSON bodies
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.