Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
@contactlab/appy
Advanced tools
Fetch API the Contactlab way
$ npm install @contactlab/appy
# --- or ---
$ yarn add @contactlab/appy
Appy try to offer a better model for fetching resources, using the standard global fetch()
function as a "backbone" and some principles from Functional Programming paradigm.
The model is built around the concepts of:
Task
)Either
)Decoder
).In order to achieve this, Appy intensely uses:
fp-ts
io-ts
Note: every sub module/lib is exported into the main index.ts
file for a comfortable use.
import {get} from '@contactlab/appy';
// same as:
// import {get} from '@contactlab/appy/lib/request';
get('http://jsonplaceholder.typicode.com/posts')
.run()
.then(result =>
result.fold(err => console.error(err), data => console.log(data))
);
This is a low level module:
it uses the standard Web API Fetch function (fetch
) in order to make a request to a resource
and wraps it in a TaskEither
monad.
So, you can:
Task
);Either
).The module tries to be as more compliant as possible with the fetch()
interface but with subtle differences:
method
is always explicit (no implicit "GET");Method
union type;fetch
's input is always a string
(no Request
objects allowed);Response
is mapped into a specific AppyResponse<Mixed>
interface;AppyResponse
headers
property is always a HeadersMap
(alias for a map of string);AppyResponse
has a body
property that is the result of parsing to JSON the string returned from response.text()
; if it cannot be parsed as JSON, body
value is just the string (both types of data are covered by the Mixed
type).RequestInit
configuration object instead remains the same.
See here for the complete list of types.
declare function request(
m: Method,
u: string,
o?: RequestInit
): TaskEither<AppyError, AppyResponse<Mixed>>;
declare function get(
u: string,
o?: RequestInit
): TaskEither<AppyError, AppyResponse<Mixed>>;
declare function post(
u: string,
o?: RequestInit
): TaskEither<AppyError, AppyResponse<Mixed>>;
declare function put(
u: string,
o?: RequestInit
): TaskEither<AppyError, AppyResponse<Mixed>>;
declare function patch(
u: string,
o?: RequestInit
): TaskEither<AppyError, AppyResponse<Mixed>>;
declare function del(
u: string,
o?: RequestInit
): TaskEither<AppyError, AppyResponse<Mixed>>;
import * as t from 'io-ts';
import {api} from '@contactlab/appy';
// same as:
// import {api} from '@contactlab/appy/lib/api';
const myApi = api({baseUri: 'http://jsonplaceholder.typicode.com'});
const token = 'secret';
const Posts = t.array(
t.type({
userId: t.number,
id: t.number,
title: t.string,
body: t.string
})
);
myApi
.get('/posts', {token, decoder: Posts})
.run()
.then(result =>
result.fold(err => console.error(err), data => console.log(data))
);
This module is tailored on the needs of the Contactlab Frontend Team.
It uses the "low-level" request
module in order to interact with Contactlab's services (REST API).
So, it is a little more opinionated:
api
) is used to "load" some configuration and returns an object with methods;baseUri
(string) key which will be prepended to every uri
;id
(string) and version
(string) which will be passed as request's headers
:
'Contactlab-ClientId': ${id}
,'Contactlab-ClientVersion': ${version}
;api
method is request()
which uses under the hood the request
module with some subtle differences:
options
parameter is mandatory and it is an extension of the RequestInit
interface;options
has a required token
(string) key which will be passed as request's Authorization: Bearer ${token}
header;options
has a required decoder
(Decoder<Mixed, A>
) key which will be used to decode the service's JSON payload;DecoderError
class which extends the AppyError
tagged union type;api
methods is TaskEither<ApiError, A>
headers
in options
object can only be a map of strings ({[k: string]: string}
); if you need to work with a Header
object you have to transform it;options
is merged with a predefined object in order to set some default values:
mode: 'cors'
headers: {'Accept': 'application/json', 'Content-type': 'application/json'}
See here for the complete list of types.
interface ApiMethods {
request: <A>(m: Method, u: string, o: ApiOptions<A>): TaskEither<ApiError, AppyResponse<A>>;
get: <A>(u: string, o: ApiOptions<A>): TaskEither<ApiError, AppyResponse<A>>;
post: <A>(u: string, o: ApiOptions<A>): TaskEither<ApiError, AppyResponse<A>>;
put: <A>(u: string, o: ApiOptions<A>): TaskEither<ApiError, AppyResponse<A>>;
patch: <A>(u: string, o: ApiOptions<A>): TaskEither<ApiError, AppyResponse<A>>;
del: <A>(u: string, o: ApiOptions<A>): TaskEither<ApiError, AppyResponse<A>>;
}
declare function api(c: ApiConfig): ApiMethods
You can find a couple of examples here.
fetch()
compatibilityThe Fetch API is available only on "modern" browsers: if you need to support legacy browsers (e.g. Internet Explorer 11 or older) or you want to use it in a Nodejs script we recommend you the excellent isomorphic-fetch
package.
Opening issues is always welcome.
Then, fork the repository or create a new branch, write your code and send a pull request.
This project uses Prettier (automatically applied as pre-commit hook), TSLint and Jest.
Tests are run with:
$ npm test
Released under the Apache 2.0 license.
FAQs
A functional wrapper around Fetch API
The npm package @contactlab/appy receives a total of 0 weekly downloads. As such, @contactlab/appy popularity was classified as not popular.
We found that @contactlab/appy demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.