A type-safe http client with a focus on zero runtime cost.
npm install @typified-web/requestA tiny request library to provide compile-time type-safe with your API specification.
- Types for each API calls with simple declarations for API,
which means:
- Code completion by API declarations with supported editor (like VSCode).
- Type validation at compile-time (design-time).
- Natural API to request resources.
- Tiny footprint for runtime of browser and NodeJS (about 4kb uncompressed).
Installation via npm:
``shell`
npm i @typified-web/request
Declare your API. E.g. the GET /greet/:name end point:
`typescript`
type YourAPI = {
'/greet/:name': {
get: {
input: {
route: {
name: string;
};
};
output: {
body: {
resCode: string;
result: {
name: string;
};
};
};
};
};
};
Then create your API request client:
`typescript
import { createRequest } from '@typified-web/request';
// the decorated reuqest function.
export default createRequest
`
> If you're using NodeJS, install node-fetch to provide the fetch implementation, like:`
>
> typescript${host}${path}
> import fetch from 'node-fetch';
>
> export default createRequest
> fetch: (path, opt) => {
> return fetch(, opt);`
> },
> });
>
Then, you can use it anywhere you like via import and get auto completion and validation for each request:
`typescript
import request from './the/newly/created/request';
// send a request.
request.endpoint('/greet/:name').get({ route: { name: 'Jack' } });
`
Code-completion and type validation works like a charm.
The API includes two parts: the API declaration for design-time and the decorated request client for runtime.
The API definition is like the Open API specification, but in a more simpler form of typescript declarations.
`typescript`
export type APISpec = {
// URL or path of the API endpoint.
[path: string]: {
// HTTP Methods.
[M in Method]?: {
// Request Specification.
input?: {
// Path parameters
route?: PathParameter;
// Path parameters
query?: PathParameter;
// Headers
headers?: Record
// Request body.
body?: Json;
};
// Response Specification.
output: {
headers?: Record
body?: Json;
};
};
};
};
The declaration is just for design-time only and will be swiped in runtime. That's why we call it almost zero-overhead.
To create a request client, you can specify your customized fetch implemenation for easy extention:
`typescript
import fetch from 'node-fetch';
const request = createRequest
fetch: (path, opt) => {
return fetch(${host}${path}, opt);`
},
});
The request client itself is complicatedly typed as it uses generics massively.
However, the usage is quite simple.
`typescript`
request.endpoint('PATH').method({ params });
The path is the resource key defined in your API specification and method is the supported method(get/post/put/patch/delete`) for your endpoint declaration. The parameters will be inferred for you.
It just add type declarations to the JSON-like API, which means the input and output are mostly JSON. Anything outside the JSON-like API is not considered well.
Help is welcomed!
MIT.