Skip to content

Service Handlers

Mario Izquierdo edited this page May 22, 2018 · 1 revision

A Twirp service definition can be defined using the DSL, or auto-generated from a .proto file.

class HelloWorldService < Twirp::Service
  package "example"
  service "HelloWorld"
  rpc :Hello, HelloRequest, HelloResponse, :ruby_method => :hello
end

This only defines the Rack app to handle HTTP requests. The Service expects a Handler to implement those requests.

Twirp Service Handler

A handler implements the rpc methods. For example a handler for HelloWorldService:

class HelloWorldHandler

  def hello(req, env)
    if req.name.empty?
      return Twirp::Error.invalid_argument("is mandatory", argument: "name")
    end

    {message: "Hello #{req.name}"}
  end

end

For each rpc method:

  • The req argument is the input request message, already serialized.
  • The env argument is the Twirp environment with data related to the request (e.g. env[:output_class]), and other fields that could have been set from before-hooks (e.g. env[:user_id] from authentication).
  • The returned value is expected to be the response message (or its attributes), or a Twirp::Error.

Start the Service

Instantiate the service with your handler impementation. Here is where you would use dependency injection or any other extra setup.

handler = HelloWorldHandler.new()
service = Example::HelloWorldService.new(handler)

The service is a Rack app. It can be mounted in a Rails app (e.g. in /config/routes.rb: mount service, at: service.full_name) and also compatible with many other HTTP frameworks.

To run as a standalone Rack app mounted on Webrick with base_url "http://localhost:3000/twirp":

require 'rack'

path_prefix = "/twirp/" + service.full_name
server = WEBrick::HTTPServer.new(Port: 3000)
server.mount path_prefix, Rack::Handler::WEBrick, service
server.start