All Projects → KnisterPeter → pretend

KnisterPeter / pretend

Licence: MIT License
A decorator based http webservice client written in typescript

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to pretend

Jotoba
A free online, self-hostable, multilang Japanese dictionary.
Stars: ✭ 87 (+155.88%)
Mutual labels:  webservice
MapML
Map Markup Language is hypertext for Web maps, like HTML is hypertext for Web pages https://maps4html.org/MapML/spec/
Stars: ✭ 48 (+41.18%)
Mutual labels:  declarative
webservice project
关于Java 使用 javax.jws 和 Axis 实现 WebService 发布和调用。
Stars: ✭ 26 (-23.53%)
Mutual labels:  webservice
theon
Declarative library to build Web API clients & SDKs for the browser and node.js
Stars: ✭ 50 (+47.06%)
Mutual labels:  declarative
f5-super-netops-container
F5 Super NetOps container images that enable Automation and Orchestration with a DevOps methodology
Stars: ✭ 24 (-29.41%)
Mutual labels:  declarative
ironhide
Ironhide, the data transformer. Main repo:
Stars: ✭ 16 (-52.94%)
Mutual labels:  declarative
convey
CSV processing and web related data types mutual conversion
Stars: ✭ 16 (-52.94%)
Mutual labels:  webservice
Helm
A graph-based SwiftUI router
Stars: ✭ 64 (+88.24%)
Mutual labels:  declarative
java-best-practice
Java学习例子,最佳实践
Stars: ✭ 19 (-44.12%)
Mutual labels:  feign
go-12factor-example
Example the 12factor app using golang
Stars: ✭ 20 (-41.18%)
Mutual labels:  webservice
spring-boot-oauth2-demo
No description or website provided.
Stars: ✭ 11 (-67.65%)
Mutual labels:  feign
react-declarative
A React form builder which interacts with a JSON endpoint to generate nested 12-column grids with input fields and automatic state management in a declarative style. Endpoint is typed by TypeScript guards (IntelliSense available). This tool is based on material-ui components, so your application will look beautiful on any device...
Stars: ✭ 17 (-50%)
Mutual labels:  declarative
ip2country
fast ip -> country lookup using asn database
Stars: ✭ 48 (+41.18%)
Mutual labels:  webservice
declarative-parser
Modern, declarative argument parser for Python 3.6+
Stars: ✭ 31 (-8.82%)
Mutual labels:  declarative
MAQS
Magenic's automation quick start
Stars: ✭ 46 (+35.29%)
Mutual labels:  webservice
terraform-provider-carvel
Carvel Terraform provider with resources for ytt and kapp to template and deploy to Kubernetes
Stars: ✭ 40 (+17.65%)
Mutual labels:  declarative
Polyfiller
Never worry about polyfills again.
Stars: ✭ 114 (+235.29%)
Mutual labels:  webservice
metagraf
metaGraf is a opinionated specification for describing a software component and what its requirements are from the runtime environment. The mg command, turns metaGraf specifications into Kubernetes resources, supporting CI, CD and GitOps software delivery.
Stars: ✭ 15 (-55.88%)
Mutual labels:  declarative
lachesis
👨‍💻 A work-in-progress web services mass scanner written in Rust
Stars: ✭ 55 (+61.76%)
Mutual labels:  webservice
dotfiles
NixOS system config & Home-Manager user config
Stars: ✭ 43 (+26.47%)
Mutual labels:  declarative

pretend

npm GitHub license build codecov renovate badge

A decorator based http webservice client build with typescript (inspired bei feign).

Features

  • Handle REST based webservices
  • Configure a decoder (defaults to JSON)
  • Generic request/response interceptor chain
  • Basic authentication
  • Request parameters (currently on GET requests)
  • Custom headers per method

Usage

Installation

Install as npm package:

npm install pretend --save

Note: To work on node.js (server-side) the fetch must be polyfilled. This could easy be done importing isomorphic-fetch.

API

class Test {

  @Headers('Accept: application/json')
  @Get('/path/{id}', true)
  public async get(id: string, parameters: any) {}

  @Post('/path')
  public async post(body: any) {}

  @Post('/path')
  public async post(@FormData('name') blob: any) {}

  @Put('/path')
  public async put() {}

  @Delete('/path/:id')
  public async delete(id: string) {}

}

async function call() {
  const client = Pretend
                  .builder()
                  .target(Test, 'http://host:port/');
  const result = await client.get('some-id', {'name': 'value'});
}

// Executes a GET request to 'http://host:port/path/some-id?name=value'
call();

Decoders, basicAuthentication and requestInterceptors are all special forms of the more generic interceptors which could be chained per request/response.

// Configure a text based decoder
const client = Pretend.builder()
  .decoder(Pretend.TextDecoder)
  .target(Test, 'http://host:port/');
// Configure basic authentication
const client = Pretend.builder()
  .basicAuthentication('user', 'pass')
  .target(Test, 'http://host:port/');
// Configure a request interceptor
const client = Pretend.builder()
  .requestInterceptor((request) => {
    request.options.headers['X-Custom-Header'] = 'value';
    return request;
  })
  .target(Test, 'http://host:port/');

Interceptors

Multiple interceptors could be added to each builder. The order of interceptor calls will result in a chain of calls like illistrated below:

// Configure a request interceptor
const client = Pretend.builder()
  .interceptor(async (chain, request) => {
    console.log('interceptor 1: request');
    const response = await chain(request);
    console.log('interceptor 1: response');
    return response;
  })
  .interceptor(async (chain, request) => {
    console.log('interceptor 2: request');
    const response = await chain(request);
    console.log('interceptor 2: response');
    return response;
  })
  .target(Test, 'http://host:port/');
             +---------------+    +---------------+
Request ---> |               | -> |               |
             | Interceptor 1 |    | Interceptor 2 | -> HTTP REST call
Response <-- |               | <- |               |
             +---------------+    +---------------+

This leads to the following console output:

interceptor 1: request
interceptor 2: request
interceptor 2: response
interceptor 1: response

Data Mappers

DataMappers could be used to map response structures to TypeScript classes. This is done using the @ResponseType decorator.

class User {
  public name: string;

  constuctor(data: { name: string }) {
    this.name = data.name;
  }
}

class API {
  @Get('/path/{id}')
  @ResponseType(User)
  public async loadUser(id: string): Promise<User> {
    /*
     * `/path/{id}` returns a JSON like this from the server:
     *
     *  {
     *    name: 'some string'
     *  }
     */
  }
}

const client = Pretend.builder().target(API, 'http://host:port/');
const result: User = await client.loadUser(1);

There is a second parameter to the @ResponseType decorator which is a transform function. The input is the server response, the output need to match the class constructor parameters.

Note: The constructor parameters are always an array!

class User {
  public get name(): string {
    return this.data.name;
  }

  constuctor(private data: { name: string }) {}
}

class API {
  @Get('/path/{id}')
  @ResponseType(User, (data) => [
    { name: `${data.firstname} ${data.lastname}` }
  ])
  public async loadUser(id: string): Promise<User> {
    /*
     * `/path/{id}` returns a JSON like this from the server:
     *
     *  {
     *    firstname: 'John',
     *    lastname: 'Doe'
     *  }
     */
  }
}

const client = Pretend.builder().target(API, 'http://host:port/');
const result: User = await client.loadUser(1);

Future ideas / Roadmap

  • Named parameters
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].