Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mitranim/xhttp
[MOVED to mitranim/js] Tiny shortcuts for using the native fetch API. Provides a fluent builder-style API for request building and response reading.
https://github.com/mitranim/xhttp
browser builder fetch http
Last synced: 15 days ago
JSON representation
[MOVED to mitranim/js] Tiny shortcuts for using the native fetch API. Provides a fluent builder-style API for request building and response reading.
- Host: GitHub
- URL: https://github.com/mitranim/xhttp
- Owner: mitranim
- Created: 2014-11-06T11:52:25.000Z (about 10 years ago)
- Default Branch: main
- Last Pushed: 2022-02-15T16:18:26.000Z (almost 3 years ago)
- Last Synced: 2025-01-03T05:05:50.080Z (22 days ago)
- Topics: browser, builder, fetch, http
- Language: JavaScript
- Homepage:
- Size: 217 KB
- Stars: 32
- Watchers: 4
- Forks: 10
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
## Overview
Tiny syntactic shortcuts for native `Request`/`Response`/`Headers`/`fetch`.
* Fluent builder-style API.
* Interoperable with built-ins.
* Shortcuts for common actions, such as:
* Building HTTP requests.
* A builder-style API is more concise and flexible than the native one.
* Handling HTTP errors in responses.
* Constructing descriptive exceptions with HTTP status and response text.
* Tiny, dependency-free, single file, native module.## TOC
* [#Usage](#usage)
* [#API](#api)
* [`function req`](#function-req)
* [`class Err`](#class-err)
* [`class Req`](#class-req)
* [`class Res`](#class-res)
* [`class Head`](#class-head)
* [`function jsonDecode`](#function-jsondecode)
* [`function jsonEncode`](#function-jsonencode)
* [Undocumented](#undocumented)
* [#Changelog](#changelog)
* [#License](#license)
* [#Misc](#misc)## Usage
In browsers and Deno, import by URL:
```js
import * as h from 'https://cdn.jsdelivr.net/npm/[email protected]/xhttp.mjs'
```When using Node or NPM-oriented bundlers like Esbuild:
```sh
npm i -E xhttp
```Example usage:
```js
const reqBody = {msg: `hello world`}
const resBody = await h.req().to(`/api`).post().json(reqBody).fetchOkJson()
```## API
### `function req`
Same as [#`new Req`](#class-req) but syntactically shorter.
### `class Err`
Subclass of `Error` for HTTP responses. The error message includes the HTTP status code, if any.
```ts
class Err extends Error {
message: string
status: int
res?: Responseconstructor(message: string, status: int, res?: Response)
}
```### `class Req`
Request builder. Does _not_ subclass `Request`. Call `.req()` to create a native request, or the various `.fetchX()` methods to immediately execute. Unlike the native request, the body is not always a stream. This means `Req` can be stored and reused several times.
```ts
class Req extends RequestInit {
/*
Similar to `fetch(this.req())`, but also constructs `Res` from the resulting
response.
*/
fetch(): Promise/*
Returns the resulting `Res` if the response is OK. If the response is
received, but HTTP status code is non-OK, throws a descriptive `Err`.Shortcut for `(await this.fetch()).okRes()`.
*/
fetchOk(): Promise// Shortcut for `(await this.fetch()).okText()`.
fetchOkText(): Promise// Shortcut for `(await this.fetch()).okJson()`.
fetchOkJson(): Promise/*
Mutates the request by applying the given options and returns the same
reference. Automatically merges headers.
*/
mut(init: RequestInit): Req// Shortcut for `new Request(this.url, this)`.
req(): Request// Sets `.url` and returns the same reference.
to(val: string | {toString(): string}): Req// Sets `.signal` and returns the same reference.
sig(val: AbortSignal): Req// Sets `.method` and returns the same reference.
meth(val: string): Req// Sets `.body` and returns the same reference. Short for "input".
inp(val: BodyInit): Req// JSON-encodes the input, sets `.body`, and sets JSON request headers.
// Does NOT set the `accept` header. Returns the same reference.
json(val: any): Req// Shortcuts for setting the corresponding HTTP method.
get(): Req
post(): Req
put(): Req
patch(): Req
delete(): Req// Idempotently sets `.headers` and returns the resulting reference.
head(): Head// Shortcuts for modifying the headers. All mutate and return the request.
headSet(key, val: string): Req
headAppend(key, val: string): Req
headDelete(key: string): Req
headMut(src: Headers | Record): Req// Class used for `.headers`. Can override in subclass.
get Head(): {new(): Head}// Class used for responses. Can override in subclass.
get Res(): {new(): Res; static from(res: Response): Res}
}
```### `class Res`
Subclass of `Response` with additional shortcuts for response handling. Always wraps a native response received from another source. [#`Req`](#class-req) automatically uses this for responses. You don't need to construct this.
```ts
class Res extends Response {
// Reference to the wrapped response.
res: Response/*
Same as the native constructor, but takes an additional response reference
to wrap. Defers the following getters to the original:get redirected
get type
get url
*/
constructor(body?: BodyInit | null, init?: ResponseInit, res: Response)/*
If `res.ok`, returns the response as-is. Otherwise throws an instance of
`Err` with the status code and response text in its error message.
*/
okRes(): Promise/*
Shortcut for `(await this.okRes()).text()`. On unsuccessful response,
throws a descriptive error. On success, returns response text.
*/
okText(): Promise/*
Shortcut for `(await this.okRes()).json()`. On unsuccessful response,
throws a descriptive error. On success, returns decoded JSON.
*/
okJson(): Promise// Class used for response errors. Can override in subclass.
get Err(): {new(): Err}// Shortcut for constructing from another response.
static from(res: Response): Res
}
```### `class Head`
Subclass of `Headers` with additional shortcuts. Used internally by [`Req`](#class-req).
```ts
class Head extends Headers {
/*
Merges the headers from the given source into the receiver. Mutates and
returns the same reference.
*/
mut(src: Headers | Record): Head/*
Overrides `Headers.prototype.set` to return the same reference, instead of
void. Also asserts input types.
*/
set(key, val: string): Head/*
Overrides `Headers.prototype.append` to return the same reference, instead of
void. Also asserts input types.
*/
append(key, val: string): Head/*
Similar to `.set`, but does nothing if the key is already present, or if the
value is empty.
*/
setOpt(key: string, val?: string): Head/*
Similar to `Set.prototype.clear`. Removes all content. Mutates and returns
the same reference.
*/
clear(): Head
}
```### `function jsonDecode`
Sanity-checking wrapper for [`JSON.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse). If the input is nil or an empty string, returns `null`. Otherwise the input must be a primitive string. Throws on other inputs, without trying to stringify them.
### `function jsonEncode`
Sanity-checking wrapper for [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). Equivalent to `JSON.stringify(val ?? null)`. If the input is `undefined`, returns `'null'` (string) rather than `undefined` (nil). Output is _always_ a valid JSON string.
### Undocumented
Some APIs are exported but undocumented to avoid bloating the docs. Check the source files and look for `export`.
## Changelog
### 0.15.3
Add `Head..setOpt`, `Res..Err`. Minor bugfixes.
### 0.15.2
Bugfix for previous version.
### 0.15.1
Add `req` shortcut.
### 0.15.0
Full revision.
* Now provides shortcuts for `fetch` and other built-ins.
* Now provides only 1 module for all environments.
* No longer uses Node APIs.
* No longer uses `XMLHttpRequest`.## License
https://unlicense.org
## Misc
I'm receptive to suggestions. If this library _almost_ satisfies you but needs changes, open an issue or chat me up. Contacts: https://mitranim.com/#contacts