Security News
pnpm 10.0.0 Blocks Lifecycle Scripts by Default
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
@flmnt/bantam
Advanced tools
Bantam is an extensible, ultra lightweight, NodeJS framework for creating RESTful microservices.
Features include:
Need to build a Python microservice? Check out Pantam
Our goal with Bantam is reduce the work bootstrapping microservices.
With Bantam you can create a basic REST API in 5 minutes or less.
First, install the required packages.
For Typescript:
% npm i @flmnt/bantam ts-node ts-node-dev typescript
% npm i @types/node @types/koa @types/koa-bodyparser @types/koa-router
Or for Javascript:
% npm i @flmnt/bantam node-dev
Once you have installed Bantam you can initialise your app; this can be done with either a brand new or existing app.
% npx @flmnt/bantam init
Follow the CLI instructions and then start building your microservice!
Bantam expects the following folder structure:
| index.ts // can have any name, it's where you run your app
| actions // where your domain logic sits
| | index.ts // primary logic lives here (might be all you need)
| | other.ts // add as many other "domains" as you like (optional)
In the root level index.ts
file add the following to run Bantam:
import Bantam from '@flmnt/bantam';
const app = new Bantam();
app.run();
In the actions
folder create the following files.
actions/index.ts
class Index {
fetchAll: (ctx) => { ... },
fetchSingle: (id, ctx) => { ... },
create: (data, ctx) => { ... },
update: (id, data, ctx) => { ... },
delete: (id, ctx) => { ... },
}
actions/other.ts
class Other {
fetchSingle: (id, ctx) => { ... },
create: (data, ctx) => { ... },
// NB: add as few methods as you need...
}
The setup above will make the following routes available:
GET / // Index.fetchAll()
GET /:id // Index.fetchSingle()
POST / // Index.create()
PATCH /:id // Index.update()
DELETE /:id // Index.delete()
GET /other/:id // Other.fetchSingle()
POST /other // Other.create()
And that's you ready to go!
Start the development server with:
% npx @flmnt/bantam serve --dev
Your application will be served on http://localhost:3000
In development mode, when you make changes to files the application will update itself.
To serve your microservice in production use:
% npx @flmnt/bantam serve
Your application is served at http://your-host:3000
You can change the port number via the configuration options.
After running npx @flmnt/bantam init
you will have a .bantamrc.js
file in your directory with some CLI config options like this:
module.exports = {
actionsFolder: 'actions',
language: 'typescript',
entrypoint: 'index.js',
};
The .bantamrc
file provides configuration options for the CLI. You only need to change it if you switch language, change your main file (entrypoint) or rename your actions folder.
To add a new action (resource) you can either create a new file in the actions folder or use the CLI to make the file for you:
% npx @flmnt/bantam action index.ts
You can add the standard methods (fetchAll
, fetchSingle
, create
, update
, delete
) to an action class which will automatically create the standard routes.
If you'd like to create custom methods for your action class you can create custom getters like this:
// GET -> /custom-method/
getCustomMethod(ctx) {
return ctx.body = 'Custom response';
}
And custom setters like this:
// POST -> /custom-method/
setCustomMethod(data, ctx) {
console.log(data);
return ctx.body = 'Custom response';
}
From version 0.2.0 onwards you can also create a do
method, which is a custom post method that also expects an identifier as part of the url.
// POST -> /custom-method/{id}
doCustomMethod(id, data, ctx) {
console.log(id, data);
return ctx.body = 'Custom response';
}
Bantam will ignore methods that are not "standard" methods or do not start with get
or set
. However if you want to ensure that your method will be ignored you can prefix the method with an underscore, like this:
_myHiddenMethod() {
// do something secret
}
Each method in an action file is passed a context (ctx) argument which you use to build a response. You can read the Koa context API here.
Creating standard responses is very straightforward.
fetchAll(ctx) {
ctx.body = 'Your response here';
}
Changing status code is also simple.
fetchAll(ctx) {
ctx.body = 'Your response here';
ctx.status = 201;
}
Adjusting headers requires you to use the ctx.set()
method.
fetchAll(ctx) {
ctx.body = 'Your response here';
ctx.status = 201;
ctx.set('Cache-Control', 'no-cache');
}
Feel free to create synchronous or asynchronous action, methods. Bantam can handle both.
async getAsyncExample() {
const result = await findRecords();
ctx.body = result;
}
getSyncExample() {
ctx.body = 'static content';
}
For advanced configuration pass an options object when instantiating Bantam.
import Bantam from '@flmnt/bantam';
const options = {
port: 80,
...
};
const app = new Bantam(options);
app.run();
The options object can have the following properties:
port: integer
Sets the port number when serving the app in production mode.
Default: 3000
devPort: integer
Sets the port number when serving the app in development mode.
Default: 3000
actionsFolder: string
The folder that contains your action files.
Default: "actions"
actionsIndexFile: string
The primary action file in your action folder.
Default: "index"
actionsFileExt: string
The file extension for action files.
Default: "ts"
onShutdown: () => Promise<void>
Asynchronous function called prior to shutdown.
Default: "async () => {})"
Bantam has been built on top of Koa, to expose the Koa application and extend Bantam's functionality you can do the following:
import Bantam from '@flmnt/bantam';
const app = new Bantam();
app.extend((koaApp) => {
koaApp.use(async (ctx, next) => {
// your code here...
await next();
});
return koaApp;
});
app.run();
If you need to add middlewear to specific routes, you'll likely want to interact with the Bantam router, which is provided by Koa Router.
import Bantam from '@flmnt/bantam';
const app = new Bantam();
app.extend((koaApp, koaRouter) => {
koaApp.use(initMiddlewear());
koaRouter.use('/url', useMiddlewear());
return [koaApp, koaRouter];
});
app.run();
NB: if you adjust the router as well as the Koa app, make sure your callback returns an array with the app and then the router (in that order)
If you're struggling to debug and issue and unsure what routes Bantam has created for you, you can use logRoutes()
to find out.
const app = new Bantam();
app.run().then((app) => {
app.logRoutes();
});
Also check trailing slashes in your urls, these are important.
In the example below the url test/1
and test/custom-method
both trigger fetchSingle()
but the url test/custom-method/
(with the trailing slash) triggers getCustomMethod()
.
// actions/test.js
// GET -> test/custom-method
// GET -> test/:id
fetchSingle() {}
// GET -> test/custom-method/
getCustomMethod() {}
We welcome feedback, suggestions and contributions.
If you have an idea you want to discuss please open an issue.
Free for personal and commerical use under the MIT License
Basil the Bantam was created with a free vector from Vectorportal.com
[1.1.2] - 2021-04-07
FAQs
A micro framework for micro services
We found that @flmnt/bantam demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.