@comparaonline/protocaller

Package that contains callers for different protocols

Usage no npm install needed!

<script type="module">
  import comparaonlineProtocaller from 'https://cdn.skypack.dev/@comparaonline/protocaller';
</script>

README

Protocaller

NPM Lib that wraps rxjs for calling request through axios and soap

Getting started 🚀

The directory is as follows:

.
└── src                                     ##MAIN CONTENT
|    ├── __tests__         
|    ├── config            
|    ├── errors            
|    ├── interfaces        
|    ├── lib               
|    ├── rest              
|    ├── soap  # Part of example server
|    ├── test
|    ├── base-request.ts
|    ├── caller-factory.ts
|    ├── enums.ts
|    ├── notifier.ts
|    └── index.ts
├── package.json
├── tsconfig.json
├── tslint.json
└── README.md

As you may see, the lib is locate at the src directory

Pre-requisites 📋

Be familiarized with RXJS lib for better understanding about the behavior of this lib

Installing

Using npm:

$ npm install @compara/protocaller

Using yarn:

$ yarn add @compara/protocaller

Examples

Rest Calls

To make rest request you will need to build a rest client, to do that, you have three possible options, Providing attributes step by step (Declarative approach), Providing an entire config and a mixture between Declarative approach and Config option:

Providing attributes step by step (Declarative approach):

  • Using an Oauth Credentials type
  import {
    CredentialsType,
    OauthConfig,
    RequestData,
    RestClientBuilder,
    RestServiceConfig
  } from "@comparaonline/protocaller"

  const OAuthConf = <OauthConfig>{
    "type": 'oauth',
    "realm": "some_realm", // this field is optional.
    "consumer": {
      "key": "some_key",
      "secret": "some_secret"
    },
    "token": {
      "key": "some_key_again",
      "secret": "some_secret_again"
    },
    signature_method: 'HMAC-SHA1' // this field is optional. 'HMAC-SHA1' is the default value 
  }
  const restClientBuilder = new RestClientBuilder()
  const reqData = <RequestData>{
    httpMethod: 'GET'
  }
  

  try {
    const client = restClientBuilder.
    setCredentials(CredentialsType.OAUTH, oAuthConf).
    setUrl('http://localhost:8080/test').
    setRetryOptions({
      retryAttempts: 3,
      exponentialDelay: 2
    }).
    build();
  
    const result = await client.call(reqData).toPromise()
    //DO SOMETHING...
  } catch (e) {
    //DO SOMETHING...
  }

  • Using JWT Credentials type
  import {
  CredentialsType,
  RequestData,
  RestClientBuilder,
  RestServiceConfig
} from "@comparaonline/protocaller"
import {JWTConfig} from "./jwt-config";

const restClientBuilder = new RestClientBuilder()
const reqData = <RequestData>{
  httpMethod: 'GET'
}

const jwtConf = <JWTConfig>{
    jwt:'some_jwt'
};
try {
  const client = restClientBuilder.setCredentials(CredentialsType.JWT, jwtConfig).setUrl('http://localhost:8080/test').setRetryOptions({
    retryAttempts: 3,
    exponentialDelay: 2
  }).build();

  const result = await client.call(reqData).toPromise()
  //DO SOMETHING...
} catch (e) {
  //DO SOMETHING...
}

  • With no Credentials
  import {
  RequestData,
  RestClientBuilder,
  RestServiceConfig
  } from "@comparaonline/protocaller"

  const restClientBuilder = new RestClientBuilder()
  const reqData = <RequestData>{
    httpMethod: 'GET'
  }
  
  try {
    const client = restClientBuilder.
    setUrl('http://localhost:8080/test').
    setRetryOptions({
      retryAttempts: 3,
      exponentialDelay: 2
    }).
    build();
  
    const result = await client.call(reqData).toPromise()
    //DO SOMETHING...
  } catch (e) {
    //DO SOMETHING...
  }

Providing an entire Config

  • Config with JWT
  import {
    CredentialsType,
    RequestData,
    RestClientBuilder,
    RestServiceConfig
  } from "@comparaonline/protocaller" 
  
  const config = <RestServiceConfig>{
    credentials: {
      type: 'jwt',
      jwt: 'some_jwt'
    },
    retryOptions: {
      retryAttempts: 2,
      exponentialDelay: 2
    },
    timeout: 3000,
    url: 'http://localhost:8080/test'
  }
  const restClientBuilder = new RestClientBuilder()
  const reqData = <RequestData>{
    httpMethod: 'GET',
    headers: {
      'some_header': 1
    }
  }
  
  try {
    const client = restClientBuilder.setConfig(config).build();
  
    const result = await client.call(reqData).toPromise()
    //DO SOMETHING...
  } catch (e) {
    //DO SOMETHING...
  }
  • Config with Oauth
  import {
    CredentialsType,
    RequestData,
    RestClientBuilder,
    RestServiceConfig
  } from "@comparaonline/protocaller"

  const config = <RestServiceConfig>{
    credentials: {
      "type": 'oauth',
      "realm": "some_realm", // this field is optional.
      "consumer": {
        "key": "some_key",
        "secret": "some_secret"
      },
      "token": {
        "key": "some_key_again",
        "secret": "some_secret_again"
      },
      signature_method: 'HMAC-SHA1' // this field is optional. 'HMAC-SHA1' is the default value 
    },
    retryOptions: {
      retryAttempts: 2,
      exponentialDelay: 2
    },
    timeout: 3000,
    url: 'http://localhost:8080/test'
  }
  const restClientBuilder = new RestClientBuilder()
  const reqData = <RequestData>{
    httpMethod: 'GET',
    headers: {
      'some_header': 1
    }
  }

  try {
    const client = restClientBuilder.
    setConfig(config).
    build();
  
    const result = await client.call(reqData).toPromise()
    //DO SOMETHING...
  } catch (e) {
    //DO SOMETHING...
  }

Mixture between Declarative approach and Config

  import {
    CredentialsType,
    OauthConfig,
    RequestData,
    RestClientBuilder,
    RestServiceConfig
  } from "@comparaonline/protocaller"

  const oAuthConf =  <OauthConfig>{
    type: "oauth",
    realm: "some_realm", // this field is optional.
    consumer: {
      key: "some_key",
      secret: "some_secret"
    },
    token: {
      key: "some_key_again",
      secret: "some_secret_again"
    },
  }

  const config = <RestServiceConfig>{
    retryOptions: {
      retryAttempts: 2,
      exponentialDelay: 2
    },
    timeout: 3000,
    url: 'http://localhost:8080/test'
  }
  const restClientBuilder = new RestClientBuilder()
  const reqData = <RequestData>{
    httpMethod: 'GET',
    headers: {
      'some_header': 1
    }
  }

  try {
    const client = restClientBuilder.
    setConfig(config).
    setCredentials(CredentialsType.OAUTH, oAuthConf).
    build();
  
    const result = await client.call(reqData).toPromise()
    //DO SOMETHING...
  } catch (e) {
    //DO SOMETHING...
  }

With this last options, notice that you are able to leverage the restClientBuilder pattern. To explain a bit, you should call first setConfig(config) method because it replaces the entire object of configuration inside the restClientBuilder and then, start to call another methods to override the desired attribute.

In addition, as you may see, exists a lot of ways to declare credentials configs, i.e:

  • With types :
    const cred = <credential_class_type>{
      // Some configs here
    }
    
  • With types as attributes:
    const cred = {
      // ...
      // Some configs here
      type: CredentialsType.OAUTH || CredentialsType.JWT,
      // Some configs here
      // ...
    }
    
  • With restClientBuilder:
      const restClientBuilder = new RestClientBuilder()
      
      try {
        const client = restClientBuilder.
        setConfig(config).
        setCredentials(CredentialsType.OAUTH || CredentialsType.JWT, some_conf).
        build();
        //DO SOMETHING...
      } catch (e) {
        //DO SOMETHING...
      }
    

There is no "Correct" way, it is just matter of what you like better.

NOTES

  • retryOptions: Its mission is simple, provides configurations to retry a request. You may notice that there are two options, retryAttempts: this tells to the client how many requests should make in case of error. exponentialDelay: this tells to the client how much should wait to make next rest call. retryOptions is an optional attribute, by default is set as following:
 {  
    retryAttempts: 2,
    exponentialDelay: 2
 }
  • Always calls build method, to generate the client.

Soap Calls

*In construction

Third parties 🛠️

  • Axios - Library to built http request
  • Rxjs - Library to handle streams of data