dio
| Package | Kind | Provides the role | Needs | Choose with |
|---|---|---|---|---|
smf_dio | infrastructure | REST API | Values in .env | -m dio |
dio sends the requests of appRest, the REST client of the app, with dio. The code of the app calls appRest.get('notes') and knows nothing of the package. What the client guarantees, such as its failures, its repeats and where the token of the user goes, comes from the role and holds with every provider; see REST API.
The role reads the address of the API from REST_BASE_URL in .env, so the module brings dart_define while that module is the only provider of the values in .env. The role uses the authentication: in an app with it, the client adds the token of the user.
What it adds to the app
| In the app | What it is |
|---|---|
dio: ^5.11.1 in the dependencies | The package. In lib/, only the file below imports it. |
lib/core/rest/dio_rest_transport.dart | DioRestTransport, which implements RestTransport of the role on one Dio, and createDio(), which creates that Dio at the first request |
| The section "dio" of the README | What an interceptor may do, and what another adapter needs |
Whichever module provides it, the role adds lib/core/rest/app_rest.dart, lib/core/rest/rest_transport.dart, lib/core/rest/session_tokens.dart in an app with sign-in, the key REST_BASE_URL, the section "REST API" of the README, two test files and the permission android.permission.INTERNET.
In the guide for coding agents of the app, the role describes the client under "REST API". The module adds where the transport is, where an interceptor goes and what it may do.
An interceptor
createDio() is where an interceptor goes, such as one of a tracing service:
Dio createDio() => Dio()..interceptors.add(TracingInterceptor());
- An interceptor that logs leaves out the header
authorizationand the query of the address, where a token or a key may be. - None repeats a request or follows a redirect.
appRestdoes both, since it knows which header may go where. - What
createDio()adds to a request goes to every address, also after a redirect and to a full address such as a presigned upload. So a credential goes through the token of the session orheaders:of the call.
Several set-cookie values cannot be told apart in the headers of a response, since a value of that header may have a comma. An API with cookies reads them in an interceptor.
How it sends
The app has one Dio, which keeps a connection open while requests follow within seconds, so those requests need no new TLS handshake. It sends each exchange as it is, with no header of Dio and no timeout of its own: the client stops each exchange itself.
Dio sends over dart:io, which reaches an http:// address with no key in the Android manifest or in Info.plist. Another adapter, such as one of native_dio_adapter for the stack of the platform, goes into httpClientAdapter in createDio(). It then needs those keys for an http:// address.
A stop ends the call at once. It closes the connection too, unless the connection is still being made. A TLS handshake on its way cannot be ended on dart:io, and since the module shares one HttpClient, neither can a TCP connect on its way: the socket closes once the system ends it.
HttpClient decodes a content-encoding of exactly gzip, and the module then leaves out that header and its content-length. A body in any other coding keeps its bytes and those headers.
In tests
RestTestServer of test/core/rest/rest_test_server.dart, which the role generates, is a local server for the tests of the app; see REST API. dio has no platform side, so a test needs no mocks.
The module keeps a test for what only it does, on the real package: that an exchange reaches Dio as it is, that a reply keeps its status and headers, how each error of Dio becomes a failure of the role, and what a stop leaves behind on a socket. See Contributing.
Choosing it
smf create asks which module provides the REST API, and the answer may be none. To choose it without the question:
smf create my_app -m dio