Installations
npm install petitservice
Developer Guide
Typescript
No
Module System
CommonJS
Node Version
20.15.0
NPM Version
10.7.0
Score
50.9
Supply Chain
95.9
Quality
77.2
Maintenance
100
Vulnerability
97.9
License
Releases
Contributors
Unable to fetch Contributors
Languages
JavaScript (100%)
Developer
melalj
Download Statistics
Total Downloads
22,312
Last Day
1
Last Week
3
Last Month
31
Last Year
1,820
GitHub Statistics
5 Stars
82 Commits
2 Forks
2 Watching
1 Branches
1 Contributors
Bundle Size
1.88 MB
Minified
545.65 kB
Minified + Gzipped
Package Meta Information
Latest Version
3.1.0
Package Id
petitservice@3.1.0
Unpacked Size
34.49 kB
Size
11.14 kB
File Count
12
NPM Version
10.7.0
Node Version
20.15.0
Publised On
25 Jun 2024
Total Downloads
Cumulative downloads
Total Downloads
22,312
Last day
0%
1
Compared to previous day
Last week
-66.7%
3
Compared to previous week
Last month
-61.7%
31
Compared to previous month
Last year
6.2%
1,820
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Petit Service 🍬
Set of helpers designed for a Microservice architecture.
Available helpers:
- Service Loader
- AMQ publisher/consumer
- Redis cache
- MongoDb client
- Express common middlewares
- Logger
- Database helpers
- Database tasks
Service Loader
Start different services (sequentially) with graceful exit handler.
Supported features:
- Check if TCP hosts are reachable
- Start Redis cache manager
- Start MongoDB client
- Start AMQ publisher/consumer
- Start HTTP server (express or http)
- Gracefully exit all services on exceptions
Full Example
1const serviceLoader = require('petitservice/lib/serviceLoader'); 2const logger = require('petitservice/lib/logger'); 3 4const config = require('./config'); 5 6return serviceLoader() 7.ping([ 8 config.apiUrl, 9 config.redisUrl, 10 config.amqpUrl, 11 config.mongoUrl, 12]) 13.cache({ host: 'localhost', port: 6379, auth_pass: 'xxx' }) 14.mongo(config.mongoUrl) 15.amq({ 16 amqUrl: 'amqp://guest:guest@localhost:5672', 17 consumerQueue: 'my-consumer-queue', 18 assertQueues: ['my-publisher-queue'], 19 consumer: (data, ack) => { 20 logger.info(data); 21 ack(); // acknowledge the message 22 }, 23}) 24.then(() => { 25 logger.info('Do something during starting...'); 26}) 27.express(() => require('./express_app.js'), config.httpPort) 28.onExit(() => { 29 logger.info('Do something during exit...'); 30}) 31.done(() => { 32 logger.info('Everything is started!'); 33});
Available functions chains
- ping(urlList, [options]): Check if hostnames are alive
urlList
(array of url to ping) format:protocol://[user:pass@]hostname:port
options.failureMax
(optional integer, how many attempts should we try before we exit the process, default: 5)options.frequency
(optional integer, how many milliseconds should wait before checking again hostnames, default: 30000)
- cache(redisOpts): Start cache for
petitservice/lib/cache
redisOpts
(required object, { host, port, auth_pass })
- mongo(mongoUrl): Start mongoDb for
petitservice/lib/mongo
mongoUrl
(required string, mongo url)
- amq(options): Connect to RabbitMQ using amqp.node, and close it when the program exit.
options
is required.options.amqUrl
(required string, amq url)options.assertQueues
(optional array, list of queue to create if they haven't been created before. if consumerQueue is set, it will be asserted as well automatically.options.consumerCb(data, ack)
(required function): handles a message to consume. It gets as parameter respectively the receiveddata
(already JSON parsed) andack
function to run when we want to acknowledge the message.options.consumerQueue
(required string): consumer queue nameoptions.consumerPrefetch
(optional integer): how many message we consume simultaneously - default: 1options.onError(err, msg)
(optional function): error handler when there's an exception on the consumer. Gets as parametererr
as error object andmsg
as raw message. Defaults a warning message.
- express(expressApp, port): Start express HTTP server, and close it when exit
expressApp
(required function that returns express app, https://github.com/expressjs/express) - We advice you to use the require inside this function.port
(integer, HTTP port. default:80
)
- then(cb): Run a function during starting
cb
(function that performs action, can return a promise as well)
- done([callback]): Add this at the end of the chain to start the service. it can take a callback function as parameter that executes when everything is loaded.
- onExit(cb): Action to perform when closing Gracefully
cb
(function that performs action, can return a promise as well)
AMQ publisher/consumer
Connect to RabbitMQ using amqp.node, Asserts queues, and consume messages from a queue.
Example using serviceLoader
1const serviceLoader = require('petitservice/lib/serviceLoader'); 2const amq = require('petitservice/lib/amq'); 3 4serviceLoader() 5.amq({ 6 amqUrl: 'amqp://guest:guest@localhost:5672', 7 consumerQueue: 'my-consumer-queue', 8 assertQueues: ['my-publisher-queue'], 9 consumer: (data, ack) => { 10 logger.info(data); 11 ack(); // acknowledge the message 12 }, 13}) 14.done(() => { 15 amq.publish({ myKey: 'myValue' }, 'my-publisher-queue'); 16});
Example without serviceLoader
1const amq = require('petitservice/lib/amq'); 2 3// Using serviceLoader 4amq.start({ 5 amqUrl: 'amqp://guest:guest@localhost:5672', 6 consumerQueue: 'my-consumer-queue', 7 assertQueues: ['my-publisher-queue'], 8 consumer: (data, ack) => { 9 logger.info(data); 10 ack(); // acknowledge the message 11 }, 12}) 13.then(() => { 14 // publish a message 15 amq.publish({ myKey: 'myValue' }, 'my-publisher-queue'); 16}); 17
Available methods
- start(options): Connect to RabbitMQ and assert publisher/consumer. Documentation on the options is available on serviceLoader
- publish(payload, queueName, [options]): Publish a payload to a queue.
- payload: (object) data to publish
- queueName: (string) where we'd like to publish the data
- options: (optional object) Publication options (for sendToQueue), default
{ persistent: false, expiration: 60000 }
- close(): Close amq connection
- getChannel(): returns active channel
- getConnection(): returns active connection
Redis Cache
Cache manager using Redis
Full example
1const cache = require('petitservice/lib/cache'); 2const logger = require('petitservice/lib/logger'); 3 4cache.start(config.redisUrl); 5 6const userId = 12; 7const getUser = (userId) => models.getUser(userId); 8 9// Get / Set / Delete 10const cacheKey = 'bob'; 11cache.getValue(cacheKey) 12.then((cachedValue) => { 13 if (!cachedValue) { 14 logger.info(`Setting value for ${cacheKey}`); 15 return cache.getValue(cacheKey, 'alice', 60); 16 } 17 logger.info(`I remember ${cachedValue}`); 18}) 19.then((cachedValue) => { 20 logger.info(`Bye ${cacheKey}`); 21 return cache.delValue(cacheKey); 22}); 23 24// Wrap a function 25cache.wrap(userId, () => models.getUser(userId), 10) 26.then((cacheUser) => { 27 logger.info(`Bonjour ${cacheUser.firstName}`); 28}); 29 30// Delayed Execution 31const id = 'abc'; 32const prm = () => { 33 return models.insertKeystroke(id, Math.random()); 34} 35cache.delayedExec(id, prm, 10); // <= prm will be discarded after 10 sec 36cache.delayedExec(id, prm, 10); // <= prm will be resolved after 10 sec
Available methods
- start(redisUrl): Instantiate the cache so that we can call get/set data.
- getValue(key): Get value by its key
- setValue(key, value, ttl): Set a value using a key (ttl - Time to live - is in seconds)
- delValue(key): Delete a value by its key
- wrap(key, fallbackPromise, ttl, isJSON): Wrap a promise in cache.
- key: (string) identifier
- fallbackPromise: (function that returns a promise) How we get the data to read/write
- ttl: (integer) Time to live in seconds
- isJSON: (boolean - default:false) encode objects to a JSON before saving into the cache
- delayedExec(identifier, prm, delayTime): Delay an promise execution of a promise across different microservices. The promise is resolved only if not another delayedExecution has been trigged during the same timeframe (delayTime).
- identifier: (string) how we identify this execution
- prm: (function that returns a promise) the promise that we want to execute
- delayTime: (integer - in seconds) timeframe when there wasn't any delayed execution with the same identifier
MongoDb client
MongoDB helpers
Full example
1const mongo = require('petitservice/lib/mongo'); 2const logger = require('petitservice/lib/logger'); 3 4return mongo.start(config.mongoUrl) 5 .then(() => { 6 const db = mongo.db(config.mongoDbname); 7 const collection = db.collection('documents'); 8 // Insert some documents 9 return collection.insertMany([ 10 {a : 1}, {a : 2}, {a : 3} 11 ]) 12 .then(() => collection.find({}).toArray()) 13 .then((docs) => logger.info(docs)); 14 }) 15 .then(() => mongo.close()); 16
Available methods
- start(mongoUrl): Instantiate the mongoDb client
- db(key): Get database instance
- close(): Close mongodb client
Express common middlewares
Set common middlewares for an express app
Full example
1const express = require('express'); 2const expressMiddleWare = require('petitservice/lib/expressMiddleWare'); 3 4const app = express(); 5expressMiddleWare.addStandard(app); 6expressMiddleWare.addCompression(app); 7 8expressMiddleWare.addLogs(app); 9 10app.get('/', (req, res) => { 11 res.send('Bonjour!'); 12}); 13 14expressMiddleWare.addErrorHandlers(app);
Available methods
- addStandard(app): Add the following middlewares:
- Disable 'x-powered-by' header
- Define 'trsut proxy' to accept forwared ip
- Body parser (json and form data)
- Set a health check endpoints '/~health' that returns 'ok'
- Remove trailing slashes on urls
- addCompression(app): Adds GZIP compression middleware
- addLogs(app, addLogs): logs http request using the logger module (See section about logger)
- addErrorHandlers(app, isHTML):
- Endpoint to handle not found pages (if isHTML is set to true it will render the view
404
) - Endpoint to handle internal errors (if isHTML is set to true it will render the view
500
)
- Endpoint to handle not found pages (if isHTML is set to true it will render the view
Logger
Log data on the console (using pino), and report errors to error if enabled
The default LogLevels depends on the NOD_ENV:
debug
fordevelopment
envinfo
forproduction
enverror
fortest
env
Full Example
1// You may also set the log level using the environment variable: LOG_LEVEL: 'debug' 2 3const logger = require('petitservice/lib/logger'); 4 5logger.debug('bonjour'); 6logger.info('un café et un croissant chaud'); 7logger.error(new Error('Something broke')); 8 9// You can use middlewares for express 10 11// Request logs 12app.use(logger.requestLogger); 13app.use(logger.errorLogger);
Exported methods
- requestLogger: Express middleware to log requests
- errorLogger: Express middleware to log errors
- error
- outputError (like error)
- warn
- info
- log
- verbose
- debug
- silly
Contribute
You are welcomed to fork the project and make pull requests. Or just file an issue or suggestion 😊
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
2 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
Found 0/28 approved changesets -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
license file not detected
Details
- Warn: project does not have a license file
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 2 are checked with a SAST tool
Score
2.3
/10
Last Scanned on 2025-01-06
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More