
Research
Security News
Lazarus Strikes npm Again with New Wave of Malicious Packages
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
Blazing fast, tiny and minimalist connect-like web framework for building REST micro-services.
You can read more: restana = faster and efficient Node.js REST APIs
npm i restana --save
Create unsecure HTTP server:
const service = require('restana')()
Passing HTTP server instance:
const https = require('https')
const service = require('restana')({
server: https.createServer({
key: keys.serviceKey,
cert: keys.certificate
})
})
Create restana HTTP server with http.createServer()
:
const http = require('http')
const service = require('restana')()
service.get('/hi', (req, res) => {
res.send({
msg: 'Hello World!'
})
})
http.createServer(service).listen(3000, '0.0.0.0', function () {
console.log('running')
})
Please take note that in the last case,
service.close()
would not be available, since restana does not have access to http server instance created byhttp.createServer
.
Optionally, learn through examples:
server
: Allows to optionally override the HTTP server instance to be used.prioRequestsProcessing
: If TRUE
, HTTP requests processing/handling is prioritized using setImmediate
. Default value: TRUE
defaultRoute
: Optional route handler when no route match occurs. Default value: ((req, res) => res.send(404))
errorHandler
: Optional global error handler function. Default value: (err, req, res) => res.send(err)
routerCacheSize
: The router matching cache size, indicates how many request matches will be kept in memory. Default value: 2000
const bodyParser = require('body-parser')
const service = require('restana')()
service.use(bodyParser.json())
const PetsModel = {
// ...
}
// registering service routes
service
.get('/pets/:id', async (req, res) => {
res.send(await PetsModel.findOne(req.params.id))
})
.get('/pets', async (req, res) => {
res.send(await PetsModel.find())
})
.delete('/pets/:id', async (req, res) => {
res.send(await PetsModel.destroy(req.params.id))
})
.post('/pets/:name/:age', async (req, res) => {
res.send(await PetsModel.create(req.params))
})
.patch('/pets/:id', async (req, res) => {
res.send(await PetsModel.update(req.params.id, req.body))
})
service.get('/version', function (req, res) {
// optionally you can send the response data in the body property
res.body = {
version: '1.0.0'
}
// 200 is the default response code
res.send()
})
Supported HTTP methods:
const methods = ['get', 'delete', 'put', 'patch', 'post', 'head', 'options', 'trace']
You can also register a route handler for all
supported HTTP methods:
service.all('/allmethodsroute', (req, res) => {
res.send(200)
})
service.start(3000).then((server) => {})
service.close().then(()=> {})
// some fake "star" handler
service.post('/star/:username', async (req, res) => {
await starService.star(req.params.username)
const stars = await starService.count(req.params.username)
res.send({ stars })
})
res.send('Hello World', 200, {
'x-response-time': 100
})
Same as in express, for restana
we have implemented a handy send
method that extends
every res
object.
Supported datatypes are:
Example usage:
service.get('/promise', (req, res) => {
res.send(Promise.resolve('I am a Promise object!'))
})
res.send(
// data payload
'Hello World',
// response code (default 200)
200,
// optional response headers (default NULL)
{
'x-cache-timeout': '5 minutes'
},
// optional res.end callback
err => { /*...*/ }
)
Optionally, you can also just send a response code:
res.send(401)
const service = require('restana')({
errorHandler (err, req, res) {
console.log(`Something was wrong: ${err.message || err}`)
res.send(err)
}
})
service.get('/throw', (req, res) => {
throw new Error('Upps!')
})
Some middlewares don't do return next()
, instead they just call next()
to finish and continue the remaining middlewares execution. The second, is a bad practice as it silence any potential Promise
rejection that happens in the downstream middlewares or handlers.
In restana (https://github.com/jkyberneees/ana/blob/master/index.js#L99) we enable async errors handling by default, however this mechanism fails when a subsequent middleware is registered containing the mentioned next()
statement to finish their execution.
const service = require('restana')()
service.use((req, res, next) => {
// do something
return next()
});
...
const service = require('restana')()
service.use('/admin', (req, res, next) => {
// do something
return next()
});
...
Connecting middlewares to specific routes is also supported:
const service = require('restana')()
service.get('/admin', (req, res, next) => {
// do something
return next()
}, (req, res) => {
res.send('admin data')
});
...
As well, multiple middleware callbacks are supported:
const service = require('restana')()
const cb0 = (req, res, next) => {
// do something
return next()
}
const cb1 = (req, res, next) => {
// do something
return next()
}
service.get('/test/:id', [cb0, cb1], (req, res) => {
res.send({ id: req.params.id })
})
Nested routers are supported as well:
const service = require('restana')()
const nestedRouter = service.newRouter()
nestedRouter.get('/hello', (req, res) => {
res.send('Hello World!')
})
service.use('/v1', nestedRouter)
...
In this example the router routes will be available under /v1
prefix. For example: GET /v1/hello
All middlewares using the
function (req, res, next)
signature format are compatible with restana.
Examples :
Since version v3.3.x
, you can also use async middlewares as described below:
service.use(async (req, res, next) => {
await next()
console.log('All middlewares and route handler executed!')
}))
service.use(logging())
service.use(jwt())
...
In the same way you can also capture uncaught exceptions inside the request processing flow:
service.use(async (req, res, next) => {
try {
await next()
} catch (err) {
console.log('upps, something just happened')
res.send(err)
}
})
service.use(logging())
service.use(jwt())
restana
is compatible with the serverless-http library, so restana based services can also run as AWS lambdas 🚀
// required dependencies
const serverless = require('serverless-http')
const restana = require('restana')
// creating service
const service = restana()
service.get('/hello', (req, res) => {
res.send('Hello World!')
})
// lambda integration
const handler = serverless(app);
module.exports.handler = async (event, context) => {
return await handler(event, context)
}
See also:
Running restana service as a lambda using AWS SAM at https://github.com/jkyberneees/restana-serverless
restana
restana based services can also run as Cloud Functions for Firebase 🚀
// required dependencies
const functions = require("firebase-functions");
const restana = require('restana')
// creating service
const service = restana()
service.get('/hello', (req, res) => {
res.send('Hello World!')
})
// lambda integration
exports = module.exports = functions.https.onRequest(app.callback());
You can read more about serving static files with restana in this link: https://itnext.io/restana-static-serving-the-frontend-with-node-js-beyond-nginx-e45fdb2e49cb
Also, the restana-static
project simplifies the serving of static files using restana and docker containers:
// ...
const service = restana()
service.get('/hello', (req, res) => {
res.send('Hello World!')
})
// using "the callback integrator" middleware
const server = http.createServer(service.callback())
//...
As a Node.js framework implementation based on the standard http
module, restana
benefits from out of the box instrumentation on
existing APM agents such as:
"Routes Naming" discovery is not supported out of the box by the Elastic APM agent, therefore we have created our custom integration.
// getting the Elastic APM agent
const agent = require('elastic-apm-node').start({
secretToken: process.env.APM_SECRET_TOKEN,
serverUrl: process.env.APM_SERVER_URL
})
// creating a restana application
const service = require('restana')()
// getting restana APM routes naming plugin
const apm = require('restana/libs/elastic-apm')
// attach route naming instrumentation before registering service routes
apm({ agent }).patch(service)
// register your routes or middlewares
service.get('/hello', (req, res) => {
res.send('Hello World!')
})
// ...
"Routes Naming" discovery is not supported out of the box by the New Relic APM agent, therefore we have created our custom integration.
// getting the New Relic APM agent
const agent = require('newrelic')
// creating a restana application
const service = require('restana')()
// getting restana APM routes naming plugin
const apm = require('restana/libs/newrelic-apm')
// attach route naming instrumentation before registering service routes
apm({ agent }).patch(service)
// register your routes or middlewares
service.get('/hello', (req, res) => {
res.send('Hello World!')
})
// ...
You can checkout restana
performance index on the "Which is the fastest" project: https://github.com/the-benchmarker/web-frameworks#full-table-1
https://goo.gl/forms/qlBwrf5raqfQwteH3
Restana version 4.x is much more simple to maintain, mature and faster!
0http
sequential router is now the default and only HTTP router.getRouter
and newRouter
methods are added for accesing default and nested routers.response
event was removed.find-my-way
router is replaced by 0http
sequential router.res.send...
turbo-http
library was dropped.You can support the maintenance of this project:
nano_3zm9steh8mb374f8be3rbytqhgzzarczhwtxhihkqt83a4m46oa3xidfiauc
rarQgNuiqF9gFLLwd5fdku4jYa9EXpiyCp
TJ5Bbf9v4kpptnRsePXYDvnYcYrS5Tyxus
bc1qcrr58venyh54ztvkqym39p9rhnxg4308t0802f
0xD73c8E63a83eBD8Df3fB3d0090f1fe7a1eEB980B
FAQs
Super fast and minimalist web framework for building REST micro-services.
The npm package restana receives a total of 3,621 weekly downloads. As such, restana popularity was classified as popular.
We found that restana demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 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.
Research
Security News
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
Security News
Socket CEO Feross Aboukhadijeh discusses the open web, open source security, and how Socket tackles software supply chain attacks on The Pair Program podcast.
Security News
Opengrep continues building momentum with the alpha release of its Playground tool, demonstrating the project's rapid evolution just two months after its initial launch.