# Introduction

Minimalistic Node.js gRPC microservice framework

npm version (opens new window) build status (opens new window) coverage status (opens new window) JavaScript Style Guide (opens new window) License (opens new window) chat on gitter (opens new window) Donate (opens new window) Buy me a coffee (opens new window)

# What is Mali?

Mali is a minimalistic gRPC (opens new window) microservice framework for Node.js (opens new window). It builds on top of existing gRPC library to provide an easy and powerful foundation to build microservice applications using modern Javasript patterns. A lot of Mali design is influenced and inspired by Koa (opens new window), but applied to gRPC concepts. If you are familiar with Koa usage, you should find development with Mali similar.

# Features

Mali builds on gRPC (opens new window) to provide unified patterns for handling different forms of calls. It strives to be minimalistic and simple, without adding additional features. Rather we try to provide mechanism for adding and composing additional features through composable middleware.

# ECMAScript 6

Mali is built with ECMAScript 6 and is designed for usage with modern asynchronous mechanisms utilizing Promises or async / await.

app.use('getUser', async function (ctx) {
  ctx.res = await app.db.get(ctx.req.id)
})

# Middleware

Cascading middleware can be composed to extend the minimal core and add additional features such as authorization, logging, database integration, and parameter and request validation.

app.use(async function logger (ctx, next) {
  const start = new Date()
  await next()
  const ms = new Date() - start
  console.log('%s %s - %s', ctx.name, ctx.type, ms);
})

# Metadata

Mali supports both header, trailer and error metadata.

app.use('getUser', async function (ctx) {
  ctx.set('headerFieldFoo', 'fooValue')
  ctx.res = await app.db.get(ctx.req.id)
  ctx.setStatus('statusFieldBar', 'barValue')
})

# Example usage

const path = require('path')
const Mali = require('mali')

const PROTO_PATH = path.resolve(__dirname, '../protos/helloworld.proto')

async function sayHello (ctx) {
  ctx.res = { message: 'Hello '.concat(ctx.req.name) }
}

function main () {
  const app = new Mali(PROTO_PATH)
  app.use({ sayHello })
  app.start('127.0.0.1:50051')
}

main()