0.0.11 • Published 3 years ago

awi v0.0.11

Weekly downloads
13
License
MIT
Repository
github
Last release
3 years ago

Awi

npm Travis CI coverage

Versatile, modern and lightweight http client based on promises.

Installation

npm i -S awi
<script src="https://cdn.jsdelivr.net/npm/awi/dist/awi.js"></script>

Requirements

NodeChromeEdgeFirefoxOperaSafari
6.13.05217291910

Usage

Basics

The most basic of requests can be executed seamlessly with Awi. Simply create a new instance and call the get sugar method with the desired URL. This call returns an instance of Awi's Response interface that has the response body, status and headers easily accessible.

import { Awi, Response } from 'awi'

const response: Response = await new Awi()
  .get('http://server.api/todos')

console.assert(typeof response.body === 'object')
console.assert(typeof response.headers === 'object')
console.assert(response.status === 200)

Awi is at its best when used in TypeScript as you can type-hint all responses and get type checks and nice auto-completion from your IDE.

import { Awi, Response } from 'awi'

interface TodoResponse extends Response {
  body: { title: string, completed: boolean }
}

const response: Response = await new Awi()
  .get<TodoResponse>('http://server.api/todos/1')

console.assert(typeof response.body.title === 'string')
console.assert(typeof response.body.completed === 'boolean')

Awi provides syntax sugar for all basic request methods. POST, PUT and PATCH helpers optionally take the body of the request as their second argument.

import { Awi, Response } from 'awi'

const response: Response = await new Awi()
  .post('http://server.api/todos', { title: 'Start using Awi.', completed: true })

console.assert(response.status === 201)

Upon receiving a 400+ response status, Awi automatically rejects the promise so that you don't have to do arbitrary checks for the response status via if statements.

import { Awi } from 'awi'

await new Awi()
  .post('http://server.api/todos', { completed: false })
  .catch(response => console.assert(response.status === 422))

Awi also provides a body helper to avoid repeating the infamous .then(res => res.body) promise callback. This helper accepts a generic type to type-hint the response body.

Note that this helper sends a GET request by default. If you desire to use a different request method, the method needs to be specified using an interceptor.

Also note that if the promise is rejected, the whole response object is returned.

import { Awi } from 'awi'

interface Todo {
  title: string
  completed: boolean
}

const todo: Todo = await new Awi()
  .body<Todo>('http://server.api/todos/1')

console.assert(typeof todo.title === 'string')
console.assert(typeof todo.completed === 'boolean')

Thanks to @bausano and his awesome data structures package, Awi has an optional helper that returns the body of the response as an Optional<T> rather than rejecting the promise.

Note that this helper sends a GET request by default. If you desire to use a different request method, the method needs to be specified using an interceptor.

Also note that if the request fails due to network issues or misconfiguration, the promise is still rejected.

import { Awi, Optional } from 'awi'

interface Todo {
  title: string
  completed: boolean
}

const todo: Optional<Todo> = await new Awi()
  .optional<Todo>('http://server.api/todos/1')

console.assert(todo instanceof Optional)

Interceptors

Request interceptors are what makes Awi stand out. Inspired by Koa, Awi provides a use method that accepts an asynchronous callback that modifies the request object.

import { Awi, Response } from 'awi'

const response: Response = await new Awi()
  .use(async req => req.base = 'http://server.api')
  .use(async req => req.path = 'todos')
  .get()

console.assert(response.status === 200))

All properties that can be modified on the request object are available in Awi's API reference.

Every request in Awi is uniquely defined by the array of interceptors assigned to the request. All Awi's helper methods are nothing more but a sugar for assigning interceptors. All requests can be sent without using the helpers via the send method.

import { Awi, Method, Response } from 'awi'

const response: Response = await new Awi()
  .use(async req => req.base = 'http://server.api')
  .use(async req => req.path = 'todos')
  .use(async req => req.method = Method.GET)
  .send()

console.assert(response.status === 200))

Although this approach is rather lenghty and using helpers is much cleaner, it provides a straightforward way to extend Awi and/or create request templates.

As you can see, the interceptor concept provides a way to create request templates for your application in a very nice and reusable way. This can be especially useful when making authorized requests.

import { Awi, Response } from 'awi'

// Define the template to be reused.
const auth = () => new Awi()
  .use(async req => req.base = 'http://server.api')
  .use(async req => req.headers['authorization'] = `Bearer ${localStorage.token}`)

// Use the template and provide further parameters.
const response: Response = await auth()
  .get('user')

console.assert(response.status === 200))

API Reference

All of Awi's functionality is summed up on the wiki page.

Why Awi?

It's lightweight

The minified file size is 12kB and we do not intend to make it bigger!

It's designed for developers, by developers

Making http requests is something every developer needs to do on daily basis, especially when it comes to TypeScript or JavaScript. Awi has a neat code base, is strictly typed and we purposefully leave documentation blocks in the built files - this way, you can read up on what each method does by simply ctrl-clicking on it!

It's flexible

You can either choose to go the easy way and using Awi's built-in helpers to execute your HTTP request as a one-liner, or you can define and extract reusable templates for your requests from scratch!

Awi is also open-source, so should you be missing any features that would make your life easier, feel free to contribute.

Credits

The interceptor pattern is heavily inspired by Koa, which is also used to create a mock server for our e2e tests.

Implemetation of executors for both web and node are inspired by no other than axios.

License

MIT

0.0.11

3 years ago

0.0.10

5 years ago

0.0.9

5 years ago

0.0.8

5 years ago

0.0.7

5 years ago

0.0.6

5 years ago

0.0.5

5 years ago

0.0.4

5 years ago

0.0.3

5 years ago

0.0.2

5 years ago

0.0.1

5 years ago