Project

leopard

0.0
A long-lived project that still receives updates
Leopard is a puma-like server for managing concurrent NATS ServiceApi endpoint workers
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies
 Project Readme

Leopard NATS ServiceApi Server

Leopard is a small framework for building concurrent NATS Service API workers. It uses Concurrent::FixedThreadPool to manage multiple workers in a single process and provides a minimal DSL for defining endpoints and middleware.

Features

  • Declarative endpoint definitions with #endpoint.

  • Grouping of endpoints with #group

  • Simple concurrency via #run with a configurable number of instances.

  • JSON aware message wrapper that gracefully handles parse errors.

  • Middleware support using #use.

  • Railway Oriented Design, using Dry::Monads for success and failure handling.

  • Dry::Configurable settings container.

  • #logger defaults to SemanticLogger (adjustable as the #logger= setting)

Requirements

  • Ruby >= 3.4.0

  • A running NATS server with the Service API enabled.

Installation

Add the gem to your project:

# Gemfile
gem 'leopard'

Then install it with Bundler.

$ bundle install

Usage

Create a service class and include Rubyists::Leopard::NatsApiServer. Define one or more endpoints. Each endpoint receives a Rubyists::Leopard::MessageWrapper object for each request to the NATS Service API endpoint that service class is is subscribed to (subject:, or name:). The message handler/callback is expected to return a Dry::Monads[:result] object, typically a Success or Failure.

class EchoService
  include Rubyists::Leopard::NatsApiServer

  endpoint :echo do |msg|
    Success(msg.data)
  end
end

Run the service by providing the NATS connection details and service options:

EchoService.run(
  nats_url: 'nats://localhost:4222',
  service_opts: { name: 'echo' },
  instances: 4
)

Middleware can be inserted around endpoint dispatch:

class LoggerMiddleware
  def initialize(app)
    @app = app
  end

  def call(wrapper)
    puts "received: #{wrapper.data.inspect}"
    @app.call(wrapper)
  end
end

EchoService.use LoggerMiddleware

Development

The project uses Minitest and RuboCop. Run tests with Rake:

$ bundle exec rake

Conventional Commits (semantic commit messages)

This project follows the Conventional Commits specification.

To contribute, please follow that commit message format, or your pull request may be rejected.

License

MIT