alphax_web 1.1.0
alphax_web: ^1.1.0 copied to clipboard
Browser Fetch HTTP, WebSocket, and application-facing client integration for AlphaX with streaming, cancellation, and browser-owned security boundaries.
alphax_web #
Run AlphaX through browser Fetch.
Keep the request API while respecting the browser's security and networking controls.
Core API · Usage and customization · Native transports · Apache-2.0
At a glance #
| Browser concern | alphax_web behavior |
|---|---|
| Transport | Fetch, exposed as an AlphaX transport |
| Protocol metadata | unknown; Fetch does not expose authoritative H1/H2/H3 information to Dart |
| Browser controls | CORS, TLS, proxy routing, connection reuse, redirects, and cookie credentials remain browser-owned |
| AlphaX policies | Authentication, replay-aware retries, in-memory cookies/cache, and generic resilience remain opt-in |
| Native controls | File paths, SPKI pinning, custom trust anchors, mTLS, explicit proxies, and upload progress are unavailable here |
Start here #
- Add
alphax_web. Its runtime dependency supplies the core AlphaX API transitively. - Create one application client with
createAlphaXAppClient(baseUrl: ...). - Configure CORS and browser credentials on the server/application boundary.
- Treat protocol metadata as
unknown; browser controls remain browser-owned.
alphax_web adds a browser Fetch transport for AlphaX. Use it when the same
transport-independent request code must run in a Flutter Web application or a
Dart application compiled for the browser. Its entry point re-exports the
public AlphaX API, so ordinary browser users need only this package import.
What you get #
- ordinary browser HTTP requests through Fetch;
- AlphaX headers, bodies, response streams, cancellation, timeouts, redirects, and normalized errors;
- browser-managed credential mode through
withCredentials; and - the same middleware layer as native AlphaX transports for authentication, cookies, caching, retries, and resilience policies.
The browser controls TLS, proxies, connection reuse, CORS, and the negotiated
HTTP version. Fetch does not expose authoritative H1/H2/H3 metadata to Dart, so
the transport reports the protocol as unknown. A concrete protocol
requirement fails closed instead of guessing.
Install #
flutter pub add alphax_web
Do not add alphax directly just to use the ordinary Web API; it is already a
runtime dependency of alphax_web. The 1.1.0 release adds the async
application-facing factory. Existing explicit transport construction remains
available for controlled or custom setups.
First request #
import 'package:alphax_web/alphax_web.dart';
Future<void> loadHealth() async {
final client = await createAlphaXAppClient(
baseUrl: 'https://example.com',
);
try {
final response = await client.get('/health');
print('${response.statusCode}: ${await response.readAsString()}');
print('protocol: ${(await response.completionMetrics).negotiatedProtocol.name}');
} finally {
await client.close();
}
}
The target server must allow the browser origin with the appropriate CORS headers. AlphaX cannot bypass browser security rules.
The compile-tested one-import example is
example/main.dart; explicit WebFetchTransport()
construction remains covered in the compatibility section below.
Configured Web client #
Web configuration remains limited to options the browser-backed transport can actually expose:
Future<AlphaXAppClient> createConfiguredClient() => createAlphaXAppClient(
baseUrl: 'https://api.example.com',
middleware: <AlphaXMiddleware>[
AlphaXAuthenticationMiddleware(
accessToken: () async => 'token-from-app',
),
],
withCredentials: true,
);
TLS, proxy routing, CORS, redirects, connection reuse, and protocol negotiation
remain browser-owned. withCredentials controls browser-managed credential
mode; it is not a native TLS, proxy, or cookie policy.
For explicit assembly and custom transports, the existing path remains available:
final client = AlphaXClient(
transport: WebFetchTransport(),
);
final customClient = AlphaXClient(
transport: MyTransport(),
);
Direct typed REST generation #
For a new typed API, add alphax_generator and build_runner as development
dependencies. The Web entry point re-exports the lightweight AlphaX
annotations, so a declaration can use one deployment import:
import 'package:alphax_web/alphax_web.dart';
part 'users_api.g.dart';
@AlphaXApi(baseUrl: 'https://example.com')
abstract class UsersApi {
factory UsersApi(AlphaXClient client) = _UsersApi;
@AlphaXGet('/users/{id}')
@AlphaXDecode('User.fromJson')
Future<User> getUser(@AlphaXPath('id') String id);
}
The generated implementation calls AlphaXClient directly and borrows the
client. Fetch, CORS, browser credentials, TLS, proxy routing, redirects, and
protocol negotiation remain browser-owned; the generator does not add native
capabilities. See alphax_generator and the
compile-tested Web fixture.
Defaults and optional policies #
WebFetchTransport follows browser security and has these defaults:
| Behavior | Default in Web |
|---|---|
| TLS and proxy | Controlled by the browser; AlphaX cannot replace them. |
| Protocol metadata | unknown; Fetch does not expose authoritative H1/H2/H3 to Dart. |
| Retries | Off until AlphaXRetryMiddleware is added. |
| Authentication | Off until authentication middleware or browser credentials are configured. |
| Cookies | Browser-managed cookies are off for cross-origin requests until withCredentials: true; an AlphaX in-memory jar is separately opt-in. |
| Cache and resilience | Off until the corresponding AlphaX middleware is added. |
The same AlphaX middleware can be added to Web for policies that do not require native controls:
final client = createAlphaXClient(
middleware: <AlphaXMiddleware>[
AlphaXAuthenticationMiddleware(
accessToken: () async => 'token-from-app',
),
AlphaXRetryMiddleware(),
AlphaXCacheMiddleware(store: AlphaXMemoryCacheStore()),
],
);
Retries still require replayable bodies, cache behavior is in-memory unless you provide another store, and browser CORS rules still apply. The Web adapter cannot add certificate pins or an explicit proxy because those controls belong to the browser. See the policy defaults and customization guide for the general policy rules.
Do not combine AlphaXCacheMiddleware with
createAlphaXClient(withCredentials: true) unless the application supplies a
stable, non-secret cache identityKey for the browser session and changes it or
clears the store on logout/account change. Browser-managed cookies are opaque to
AlphaX, so the cache cannot discover that identity itself. If browser identity
can change without the application observing it, leave AlphaX caching off for
those requests.
Cookies and browser credentials #
For browser-managed cookies, opt in deliberately:
final client = createAlphaXClient(withCredentials: true);
withCredentials is a browser Fetch setting. Cross-origin servers must also
return compatible CORS and credential headers. If the application needs an
explicit, transport-neutral in-memory cookie jar, add
AlphaXCookieMiddleware(AlphaXCookieJar()) from alphax instead.
Server-Sent Events with Fetch #
The Web entry point re-exports AlphaXSseParser, so an SSE response can use
the same one-import deployment path:
import 'package:alphax_web/alphax_web.dart';
Future<void> consumeSse(AlphaXClient client, Uri uri) async {
final response = await client.send(
AlphaXRequest(
method: HttpMethod.get,
uri: uri,
headers: AlphaXHeaders({'accept': 'text/event-stream'}),
),
);
await for (final event in response.stream.transform(AlphaXSseParser())) {
print('${event.event ?? 'message'}: ${event.data}');
}
}
This uses Fetch response streaming, not the browser EventSource API. CORS,
TLS, proxy routing, connection behavior, and browser protocol selection remain
browser-owned. The parser exposes IDs and retry hints but never reconnects or
sends Last-Event-ID; cancellation remains the normal AlphaX request token.
See the core SSE example for the parser contract.
WebSocket #
Use the browser connector from the same Web deployment import:
import 'package:alphax_web/alphax_web.dart';
Future<void> useWebSocket(Uri uri) async {
final connector = createAlphaXWebSocketConnector();
final socket = await connector.connect(
uri,
protocols: <String>['alpha.v1'],
);
try {
final firstMessage = socket.messages.first;
await socket.send(const AlphaXWebSocketMessage.text('hello'));
print(await firstMessage);
} finally {
await socket.close();
}
}
The connector uses the browser WebSocket API through the maintained
package:web_socket abstraction. Text and binary messages remain distinct,
the negotiated subprotocol is reported by the browser, and socket.done
provides terminal close information. There is no EventSource-style automatic
reconnect, retry, replay, or resend queue.
Browser WebSocket does not permit arbitrary request headers, so the portable
connector intentionally has no header parameter and reports
connector.capabilities.customHeaders as AlphaXSupport.unsupported. Browser
TLS, origin, cookies, CSP, proxy/network policy, and connection behavior remain
browser-owned. Use browser-managed cookies, a supported subprotocol, or an
application-level authentication message where appropriate; AlphaX never
transforms authorization headers into query parameters. Use wss: when the
browser connection must be secure; AlphaX does not add a trust-all or
certificate-bypass path. The compile-tested example is
example/websocket.dart.
Browser boundaries #
- H3 is not guaranteed; provider, server, proxy, and network conditions decide the actual protocol.
- Fetch cannot authoritatively report H1/H2/H3, so
protocolRequirementis rejected withAlphaXProtocolRequirementException. - Native file paths, custom trust anchors, SPKI pinning, mTLS, explicit proxy endpoints, and upload progress are unavailable in this adapter.
- Request bodies are buffered before Fetch dispatch because browser Fetch does not provide the AlphaX native streaming-upload contract here.
- Redirect behavior and credential handling remain subject to browser Fetch and CORS rules.
Use alphax_native for Android, iOS,
macOS, Linux, and Windows transport adapters. Use
alphax
directly when you provide another transport.
If a browser limitation is unacceptable, move that operation to a native transport and check its reported capabilities before configuring TLS, proxy, or protocol requirements. AlphaX will fail closed rather than pretending that the browser can enforce a control it cannot observe.
For direct AlphaX usage, see alphax. For
native Flutter transports, use alphax_native.
Add alphax_generator for direct
typed REST generation or alphax_test
for deterministic test transports.
The package is licensed under Apache-2.0. The 1.1.0 release adds the
application-facing browser factory. The browser facade is additive to the
existing Web transport and explicit transport construction path.