
Product
Announcing Socket Fix 2.0
Socket Fix 2.0 brings targeted CVE remediation, smarter upgrade planning, and broader ecosystem support to help developers get to zero alerts.
moleculer-http-client
Advanced tools
HTTP client mixin that allows Moleculer services to communicate with remote REST APIs
A tiny wrapper around got HTTP client that allows Moleculer services to communicate with REST APIs. Why got? Because reasons.
npm install moleculer-http-client --save
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
}
}
},
};
get
HTTP GET action
Property | Type | Default | Description |
---|---|---|---|
url | String | required | URL |
opt | Object | optional | Request options |
Type: Promise
, Stream
post
HTTP POST action
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 passurl
andopt
andctx.params
to pass stream data
Type: Promise
put
HTTP PUT action
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 passurl
andopt
andctx.params
to pass stream data
Type: Promise
patch
HTTP PATCH action
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 passurl
andopt
andctx.params
to pass stream data
Type: Promise
delete
HTTP DELETE action
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 passurl
andopt
andctx.params
to pass stream data
Type: Promise
_get
HTTP GET method
Property | Type | Default | Description |
---|---|---|---|
url | String | required | URL |
opt | Object | optional | Request options |
Type: Promise
, Stream
_post
HTTP POST method
Property | Type | Default | Description |
---|---|---|---|
url | String | required | URL |
opt | Object | optional | Request options |
streamPayload | Stream | optional | Stream payload |
Type: Promise
_put
HTTP PUT method
Property | Type | Default | Description |
---|---|---|---|
url | String | required | URL |
opt | Object | optional | Request options |
streamPayload | Stream | optional | Stream payload |
Type: Promise
_patch
HTTP PATCH method
Property | Type | Default | Description |
---|---|---|---|
url | String | required | URL |
opt | Object | optional | Request options |
streamPayload | Stream | optional | Stream payload |
Type: Promise
_delete
HTTP DELETE method
Property | Type | Default | Description |
---|---|---|---|
url | String | required | URL |
opt | Object | optional | Request options |
Type: Promise
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' } }
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' } }
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));
});
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);
});
});
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 aboutCache-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' } }
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
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' } }
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}`);
}
}
}
});
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");
}
}
}
});
$ npm test
Please send pull requests improving the usage and fixing bugs, improving documentation and providing better examples.
The project is available under the MIT license.
Copyright (c) 2016-2020 MoleculerJS
0.4.2 (2021-06-17)
index.d.ts
) to support use of import
statements instead of require
in moleculerjs TS projects to resolve the typescript-eslint/no-var-requires
error that is thrown during the linting.<a name="0.4.1"></a>
FAQs
HTTP client mixin that allows Moleculer services to communicate with remote REST APIs
The npm package moleculer-http-client receives a total of 425 weekly downloads. As such, moleculer-http-client popularity was classified as not popular.
We found that moleculer-http-client demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 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.
Product
Socket Fix 2.0 brings targeted CVE remediation, smarter upgrade planning, and broader ecosystem support to help developers get to zero alerts.
Security News
Socket CEO Feross Aboukhadijeh joins Risky Business Weekly to unpack recent npm phishing attacks, their limited impact, and the risks if attackers get smarter.
Product
Socket’s new Tier 1 Reachability filters out up to 80% of irrelevant CVEs, so security teams can focus on the vulnerabilities that matter.