Skip to main content

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

()
String getName(Ctx ctx) {
final Request request = ctx.request;
assert(request == extractRequest(ctx));
assert(request.headersAll is Map<String, List<String>>);
return '';
}

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';

()
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 '';
}