# Fetch API Baseline: GET of a data: URI produces a result. This allows for functional testing and interaction with `await`. ```typescript= let { UrlRequest } = import("TBD"); doAsync { () extends GeneratorFn;; let request = new UrlRequest("data:type/text;Hello, World!"); request.method = "GET"; // default // Could add headers which would be ignored with data: let response = request.fetch(); do { await(response.bodyText) } orelse do { ... }; } ``` ```typescript= export class UrlRequest { // consider making this a setter so that you can't do: req.method = "NO_METHOD_BY_THIS_NAME_MAKES_ANY_SENSE!!!"; // TODO: make an enum // (sealed class of request subtypes? and factory method? this does somewhat defeat builder) public var method: String; public constructor(url: String); public addHeader(name: String, value: String); public fetch(): UrlResponse; // TODO: extend to allow adding POST parameters and bodies } export class UrlResponse { public get headers(): Deferred<Map<String, String> | Null>; public get body(): Deferred<Bytes | Null>; public get bodyText(): Deferred<String | Null>; public get bodyType(): Deferred<MimeType | Null>; } export /* sealed */ interface Deferred<T> { public complete: Boolean; /** Non-blocking result fetch where no-value-yet produces null. */ public getOrNull(): T | Null; public cancel(): Void /* maybe bubble here */; // Maybe have async be a method or getter? } // Macro that uses pause export let await<T extends AnyValue>(d: Deferred<T>): T | Bubble; export let fetch(req: UrlRequest): UrlResponse; // Schedules for execution. export let doAsync(g: Generator<*, Never>); ``` ## Concerns Tom: Splatting would suffice for a non-mutable request configuration Shaw: prefer setters to set methods Shaw: Hey if we can do this kind of system effect, what about designing a Filesystem API?