![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
@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
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.