All Projects β†’ moleculerjs β†’ moleculer-http-client

moleculerjs / moleculer-http-client

Licence: MIT license
HTTP client mixin that allows Moleculer services to communicate with remote REST APIs

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to moleculer-http-client

Got
🌐 Human-friendly and powerful HTTP request library for Node.js
Stars: ✭ 10,620 (+75757.14%)
Mutual labels:  http-client, http-request
Ky
🌳 Tiny & elegant JavaScript HTTP client based on the browser Fetch API
Stars: ✭ 7,047 (+50235.71%)
Mutual labels:  http-client, http-request
centra
Core Node.js HTTP client
Stars: ✭ 52 (+271.43%)
Mutual labels:  http-client, http-request
Wretch
A tiny wrapper built around fetch with an intuitive syntax. 🍬
Stars: ✭ 2,285 (+16221.43%)
Mutual labels:  http-client, http-request
requests-rs
Rust HTTP client library styled after awesome Python requests
Stars: ✭ 37 (+164.29%)
Mutual labels:  http-client
NClient
πŸ’« NClient is an automatic type-safe .Net HTTP client that allows you to call web service API methods using annotated interfaces or controllers without boilerplate code.
Stars: ✭ 25 (+78.57%)
Mutual labels:  http-client
resto
πŸ”— a CLI app can send pretty HTTP & API requests with TUI
Stars: ✭ 113 (+707.14%)
Mutual labels:  http-client
jetty-reactive-httpclient
Jetty ReactiveStreams HttpClient
Stars: ✭ 63 (+350%)
Mutual labels:  http-client
Rx.Http
A reactive way to make HTTP Request in .NET Core πŸš€
Stars: ✭ 62 (+342.86%)
Mutual labels:  http-client
theon
Declarative library to build Web API clients & SDKs for the browser and node.js
Stars: ✭ 50 (+257.14%)
Mutual labels:  http-client
restofus
Restofus - a cross-platform (REST) API client.
Stars: ✭ 18 (+28.57%)
Mutual labels:  http-client
http
Tiny, embeddable HTTP client with simple API for the browser
Stars: ✭ 21 (+50%)
Mutual labels:  http-client
waspy
WASP framework for Python
Stars: ✭ 43 (+207.14%)
Mutual labels:  http-client
rawhttp
HTTP library to make it easy to deal with raw HTTP.
Stars: ✭ 156 (+1014.29%)
Mutual labels:  http-client
cute-http
δΈ€δΈͺ基于axiosε°θ£…ηš„ζ›΄ζ˜“η”¨ηš„http库。
Stars: ✭ 18 (+28.57%)
Mutual labels:  http-client
angular6-httpclient-example
Angular 6 HttpClient: Consume RESTful API Example
Stars: ✭ 38 (+171.43%)
Mutual labels:  http-client
framework
Aplus Full-Stack Framework
Stars: ✭ 172 (+1128.57%)
Mutual labels:  http-client
restler
Restler is a beautiful and powerful Android app for quickly testing REST API anywhere and anytime.
Stars: ✭ 120 (+757.14%)
Mutual labels:  http-client
relay
Relay lets you write HTTP requests as easy to read, structured YAML and dispatch them easily using a CLI. Similar to tools like Postman
Stars: ✭ 22 (+57.14%)
Mutual labels:  http-client
lhs
βš›οΈ REST services accelerator: Rails gem providing an easy, active-record-like interface for http (hypermedia) json services
Stars: ✭ 130 (+828.57%)
Mutual labels:  http-client

Moleculer logo

Build Status Coverage Status GitHub license npm Downloads

moleculer-http-client

A tiny wrapper around got HTTP client that allows Moleculer services to communicate with REST APIs. Why got? Because reasons.

Features

  • Make HTTP requests from Actions and Events
  • Stream data
  • Cache data
  • Customizable log messages and errors

Install

npm install moleculer-http-client --save

Service Settings

Use httpClient field to configure your got client.

module.exports = {
  name: "http",
  
  /**
   * Moleculer settings
   */
  settings: {
    // HTTP client settings
    httpClient: {
      // Boolean value indicating whether request should be logged or not
      logging: true,

      // Log request function
      logOutgoingRequest: logOutgoingRequest,

      // Log response function
      logIncomingResponse: logIncomingResponse,

      // Format the Response
      responseFormatter: "body", // one of "body", "headers", "status", "raw"

      // Format the Errors
      errorFormatter: errorFormatter,

      // Got Client options
      defaultOptions: {
        // Put here any Got available option that can be used to extend Got client
      }
    }
  },
};

Service Actions

get

HTTP GET action

Parameters

Property Type Default Description
url String required URL
opt Object optional Request options

Returns

Type: Promise, Stream

post

HTTP POST action

Parameters

Property Type Default Description
url String required URL
opt Object optional Request options
streamPayload Stream optional Stream payload

Note: When streaming use ctx.meta to pass url and opt and ctx.params to pass stream data

Returns

Type: Promise

put

HTTP PUT action

Parameters

Property Type Default Description
url String required URL
opt Object optional Request options
streamPayload Stream optional Stream payload

Note: When streaming use ctx.meta to pass url and opt and ctx.params to pass stream data

Returns

Type: Promise

patch

HTTP PATCH action

Parameters

Property Type Default Description
url String required URL
opt Object optional Request options
streamPayload Stream optional Stream payload

Note: When streaming use ctx.meta to pass url and opt and ctx.params to pass stream data

Returns

Type: Promise

delete

HTTP DELETE action

Parameters

Property Type Default Description
url String required URL
opt Object optional Request options
streamPayload Stream optional Stream payload

Note: When streaming use ctx.meta to pass url and opt and ctx.params to pass stream data

Returns

Type: Promise

Service Methods

_get

HTTP GET method

Parameters

Property Type Default Description
url String required URL
opt Object optional Request options

Returns

Type: Promise, Stream

_post

HTTP POST method

Parameters

Property Type Default Description
url String required URL
opt Object optional Request options
streamPayload Stream optional Stream payload

Returns

Type: Promise

_put

HTTP PUT method

Parameters

Property Type Default Description
url String required URL
opt Object optional Request options
streamPayload Stream optional Stream payload

Returns

Type: Promise

_patch

HTTP PATCH method

Parameters

Property Type Default Description
url String required URL
opt Object optional Request options
streamPayload Stream optional Stream payload

Returns

Type: Promise

_delete

HTTP DELETE method

Parameters

Property Type Default Description
url String required URL
opt Object optional Request options

Returns

Type: Promise

Usage

Actions

Action Example

const { ServiceBroker } = require("moleculer");
const HTTPClientService = require("moleculer-http-client");

// Create broker
let broker = new ServiceBroker();

// Create a service
broker.createService({
  name: "http",

  // Load HTTP Client Service  
  mixins: [HTTPClientService]
});

// Start the broker
broker.start().then(() => {
  broker
    // Make a HTTP GET request
    .call("http.get", {
      url: "https://httpbin.org/json",
      opt: { responseType: "json" }
    })
    .then(res => broker.logger.info(res))
    .catch(error => broker.logger.error(error));
});

Result

INFO  http-client/HTTP: => HTTP GET to "https://httpbin.org/json"
INFO  http-client/HTTP: <= HTTP GET to "https://httpbin.org/json" returned with status code 200
INFO  http-client/BROKER: { slideshow: { author: 'Yours Truly', date: 'date of publication', slides: [ [Object], [Object] ], title: 'Sample Slide Show' } }

Events

Event Example

const { ServiceBroker } = require("moleculer");
const HTTPClientService = require("moleculer-http-client");

// Create broker
let broker = new ServiceBroker();

// Create a service
broker.createService({
  name: "http",

  // Load HTTP Client Service
  mixins: [HTTPClientService],

  events: {
    // Register an event listener
    async "some.Event"(request) {
      this.logger.info("Caught an Event");
      // Use service method to make a request
      const res = await this._get(request.url, request.opt);
      this.logger.info("Printing Payload");
      // Print the response data
      this.logger.info(res.body);
    }
  }
});

// Start the broker
broker.start().then(() => {
  broker
    // Emit some event
    .emit("some.Event", {
      url: "https://httpbin.org/json",
      opt: { responseType: "json" }
    });
});

Result

INFO  http-client/HTTP: Caught an Event
INFO  http-client/HTTP: => HTTP GET to "https://httpbin.org/json"
INFO  http-client/HTTP: <= HTTP GET to "https://httpbin.org/json" returned with status code 200
INFO  http-client/HTTP: Printing Payload
INFO  http-client/HTTP: { slideshow: { author: 'Yours Truly', date: 'date of publication', slides: [ [Object], [Object] ], title: 'Sample Slide Show' } }

Stream

GET Stream

const { ServiceBroker } = require("moleculer");
const HTTPClientService = require("moleculer-http-client");
const fs = require("fs");

// Create broker
let broker = new ServiceBroker({
  nodeID: "http-client"
});

// Create a service
broker.createService({
  name: "http",

  // Load HTTP Client Service
  mixins: [HTTPClientService]
});

// Start the broker
broker.start().then(() => {
  broker
    // Make a HTTP GET request
    .call("http.get", {
      url: "https://sindresorhus.com/",
      opt: { isStream: true }
    })
    .then(res => {
      const filePath = "./examples/stream-get/file.md";
      res.pipe(fs.createWriteStream(filePath, { encoding: "utf8" }));

      res.on("response", response => {
        broker.logger.info(response.statusCode);
      });
    })
    .catch(error => broker.logger.error(error));
});

POST Stream

const { ServiceBroker } = require("moleculer");
const HTTPClientService = require("moleculer-http-client");
const ApiGateway = require("moleculer-web");
const fs = require("fs");

// Create broker
let broker = new ServiceBroker({
  nodeID: "http-client"
});

// Create a HTTP Client Service
broker.createService({
  name: "http",

  // Load HTTP Client Service
  mixins: [HTTPClientService]
});

// Create HTTP Server Services
broker.createService({
  name: "api",
  mixins: [ApiGateway],
  settings: {
    port: 4000,
    routes: [
      {
        path: "/stream",
        bodyParsers: { json: false, urlencoded: false },
        aliases: { "POST /": "stream:api.postStream" }
      }
    ]
  },

  actions: {
    postStream(ctx) {
      return new Promise((resolve, reject) => {
        const stream = fs.createWriteStream(
          "./examples/stream-post/stored-data.md"
        );

        stream.on("close", async () => {
          resolve({ fileName: `file.md`, method: "POST" });
        });

        // Return error to the user
        stream.on("error", err => {
          reject(err);
        });

        // Pipe the data
        ctx.params.pipe(stream);
      });
    }
  }
});

// Start the broker
broker.start().then(() => {
  const streamFile = "./examples/stream-post/data-to-stream.md";
  const stream = fs.createReadStream(streamFile, { encoding: "utf8" });

  // Pass stream as ctx.params
  // Pass URL and options in ctx.meta
  const req = broker.call("http.post", stream, {
    meta: { url: "http://localhost:4000/stream", isStream: true }
  });

  req.then(res => {
    broker.logger.info(res.statusCode);
  });
});

Cache

Moleculer Cache

If you are using actions to make HTTP requests then you can use Moleculer's cache to cache responses.

Please note that when using Moleculer's cache you will be ignoring Cache-Control header field. If you care about Cache-Control then you should use Got's cache.

Example of Moleculer Cache

const { ServiceBroker } = require("moleculer");
const HTTPClientService = require("moleculer-http-client");

// Create broker
let broker = new ServiceBroker({
  nodeID: "http-client",
  // Enable Moleculer Cache
  cacher: "Memory"
});

// Create a service
broker.createService({
  name: "http",

  // Load HTTP Client Service
  mixins: [HTTPClientService],

  actions: {
    get: {
      // Enable cache for GET action
      // More info: https://moleculer.services/docs/0.13/caching.html
      cache: true
    }
  }
});

// Start the broker
broker.start().then(() => {
  broker
    // Make a HTTP GET request
    .call("http.get", {
      url: "https://httpbin.org/json",
      opt: { responseType: "json" }
    })
    .then(res => broker.logger.info(res.body))
    .then(() =>
      broker.call("http.get", {
        url: "https://httpbin.org/json",
        opt: { responseType: "json" }
      })
    )
    .then(res => broker.logger.info(res.body))
    .catch(error => broker.logger.error(error));
});

Result

            INFO  http-client/HTTP: => HTTP GET to "https://httpbin.org/json"
            INFO  http-client/HTTP: <= HTTP GET to "https://httpbin.org/json" returned with status code 200
Request ->  INFO  http-client/BROKER: { slideshow: { author: 'Yours Truly', date: 'date of publication', slides: [ [Object], [Object] ], title: 'Sample Slide Show' } }
Cache   ->  INFO  http-client/BROKER: { slideshow: { author: 'Yours Truly', date: 'date of publication', slides: [ [Object], [Object] ], title: 'Sample Slide Show' } }

Got's Cache

If you are using methods or you care about Cache-Control header option then you should use Got's cache.

Example of Got cache

const { ServiceBroker } = require("moleculer");
const HTTPClientService = require("moleculer-http-client");

// Using JS Map as cache
const cacheMap = new Map();

// Create broker
let broker = new ServiceBroker({
  nodeID: "http-client"
});

// Create a service
broker.createService({
  name: "http",

  // Load HTTP Client Service
  mixins: [HTTPClientService],

  settings: {
    httpClient: {
      defaultOptions: {
        // Set Got's built-in cache
        // More info: https://www.npmjs.com/package/got#cache-1
        cache: cacheMap
      }
    }
  }
});

// Start the broker
broker.start().then(() => {
  broker
    // Make a HTTP GET request
    .call("http.get", {
      url: "https://httpbin.org/cache/150",
      opt: { responseType: "json" }
    })
    .then(res => broker.logger.info(res.isFromCache))
    .then(() =>
      broker.call("http.get", {
        url: "https://httpbin.org/cache/150",
        opt: { responseType: "json" }
      })
    )
    .then(res => broker.logger.info(res.isFromCache))
    .catch(error => broker.logger.error(error));
});

Result

INFO  http-client/HTTP: => HTTP GET to "https://httpbin.org/cache/150"
INFO  http-client/HTTP: <= HTTP GET to "https://httpbin.org/cache/150" returned with status code 200
INFO  http-client/BROKER: false
INFO  http-client/HTTP: => HTTP GET to "https://httpbin.org/cache/150"
INFO  http-client/HTTP: **CACHED** HTTP GET to "https://httpbin.org/cache/150" returned with status code 200
INFO  http-client/BROKER: true

Got Instance

If you need to do some fancy request (e.g., HEAD, TRACE, OPTIONS) you can directly call the got client available at _client.

const { ServiceBroker } = require("moleculer");
const HTTPClientService = require("moleculer-http-client");

// Create broker
let broker = new ServiceBroker({
  nodeID: "http-client"
});

// Create a service
broker.createService({
  name: "http",

  // Load HTTP Client Service
  mixins: [HTTPClientService],

  actions: {
    async fancyRequest(ctx) {
      try {
        // Direct call to Got Client
        // Can be any Got supported HTTP Method
        return await this._client(ctx.params.url, ctx.params.opt);
      } catch (error) {
        throw error;
      }
    }
  }
});

// Start the broker
broker.start().then(() => {
  broker
    // Make a fancy request
    .call("http.fancyRequest", {
      url: "https://httpbin.org/json",
      opt: { method: "GET", responseType: "json" }
    })
    .then(res => broker.logger.info(res.body))
    .catch(error => broker.logger.error(error));
});
INFO  http-client/HTTP: => HTTP GET to "https://httpbin.org/json"
INFO  http-client/HTTP: <= HTTP GET to "https://httpbin.org/json" returned with status code 200
INFO  http-client/BROKER: { slideshow: { author: 'Yours Truly', date: 'date of publication', slides: [ [Object], [Object] ], title: 'Sample Slide Show' } }

Customization

Log Messages

    const service = broker.createService({
      name: "http",

      mixins: [MoleculerHTTP],

      settings: {
        httpClient: {
          // Input is Got's options object. More info: https://www.npmjs.com/package/got#options
          logOutgoingRequest: options => {
            console.log(`-----> Request ${options.href}`);
          },

          // Input is Got's response object: More info: https://www.npmjs.com/package/got#response
          logIncomingResponse: response => {
            console.log(`<----- Response Status Code ${response.statusCode}`);
          }
        }
      }
    });

Errors

    const service = broker.createService({
      name: "http",

      mixins: [MoleculerHTTP],

      settings: {
        httpClient: {
          // Custom error handler function
          // Input error is Got's error. More info: https://www.npmjs.com/package/got#errors
          errorFormatter: error => {
            return new Error("Custom Error");
          }
        }
      }
    });

Test

$ npm test

Contribution

Please send pull requests improving the usage and fixing bugs, improving documentation and providing better examples.

License

The project is available under the MIT license.

Contact

Copyright (c) 2016-2020 MoleculerJS

@moleculerjs @MoleculerJS

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].