Skip to content

Commit

Permalink
Merge pull request #18 from collectiveidea/handler-packages
Browse files Browse the repository at this point in the history
Look for handlers in both the fully-qualified namespace, or root namespace.
  • Loading branch information
danielmorrison authored Sep 12, 2024
2 parents f8b5d53 + 8c387b0 commit 874cdfd
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 18 deletions.
3 changes: 3 additions & 0 deletions .standard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ ruby_version: 2.7
plugins:
- standard-performance
- standard-rails
ignore:
- '**/*_pb.rb'
- '**/*_twirp.rb'
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ gem "rake"
gem "debug"
gem "rspec-rails"
gem "sqlite3", "~> 1.4"
gem "standard"
gem "standard", ">= 1.35.1"
gem "standard-performance"
gem "standard-rails"
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,26 @@ end

Each handler method should return the appropriate Protobuf, or a `Twirp::Error`.

TODO: Give more examples of both
#### Packages and Namespacing

Handlers can live in directories that reflect the service's package. For example, `haberdasher.proto` defines:

```protobuf
package twirp.example.haberdasher;
```

You can use the full path, or because many projects have only one namespace, we also let you skip the namespace for simplicity:

We look for the handler in either location:

`app/handlers/twirp/example/haberdasher/haberdasher_service_handler.rb` defines `Twirp::Example::Haberdasher::HaberdasherServiceHandler`

or

`app/handlers/haberdasher_service_handler.rb` defines `HaberdasherServiceHandler`


TODO: Give more examples of handlers

### Familiar Callbacks

Expand Down
8 changes: 7 additions & 1 deletion lib/twirp/rails/dispatcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ module Twirp
module Rails
class Dispatcher
def initialize(service_class)
@service_handler = "#{service_class.service_name}Handler".constantize
# Check for a handler in the service's namespace, or in the root namespace
# e.g. Twirp::Example::Cobbler::CobblerHandler or ::CobblerHandler
@service_handler = if Object.const_defined?("#{service_class.module_parent}::#{service_class.service_name}Handler")
"#{service_class.module_parent}::#{service_class.service_name}Handler".constantize
else
"#{service_class.service_name}Handler".constantize
end
end

def respond_to_missing?(method, *)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Twirp
module Example
module Cobbler
class CobblerHandler < Twirp::Rails::Handler
def make_shoe
# We can return a Twirp::Error when appropriate
if request.inches < 12
return Twirp::Error.invalid_argument("is too small", argument: "inches")
end

# Build the reponse
Twirp::Example::Cobbler::Shoe.new(
inches: request.inches,
name: "Pork Pie",
color: "Tan"
)
end
end
end
end
end
22 changes: 8 additions & 14 deletions spec/rails_app/lib/haberdasher_pb.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion spec/rails_app/lib/haberdasher_twirp.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Code generated by protoc-gen-twirp_ruby 1.10.0, DO NOT EDIT.
# frozen_string_literal: true

# Generated by the protoc-gen-twirp_ruby gem v1.1.1. DO NOT EDIT!
# source: haberdasher.proto

require "twirp"
require_relative "haberdasher_pb"

Expand Down
20 changes: 20 additions & 0 deletions spec/rails_app/lib/twirp/example/cobbler/cobbler_pb.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions spec/rails_app/lib/twirp/example/cobbler/cobbler_twirp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

# Generated by the protoc-gen-twirp_ruby gem v1.1.1. DO NOT EDIT!
# source: twirp/example/cobbler/cobbler.proto

require "twirp"
require_relative "cobbler_pb"

module Twirp
module Example
module Cobbler
class CobblerService < ::Twirp::Service
package "twirp.example.cobbler"
service "Cobbler"
rpc :MakeShoe, Size, Shoe, ruby_method: :make_shoe
end

class CobblerClient < ::Twirp::Client
client_for CobblerService
end
end
end
end
23 changes: 23 additions & 0 deletions spec/rails_app/proto/twirp/example/cobbler/cobbler.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// A close copy of haberdasher.proto
// We're putting this in /proto/twirp/example/cobbler/ so that we can test namespace handling
syntax = "proto3";

package twirp.example.cobbler;

// Cobbler service makes shoes for clients.
service Cobbler {
// MakeShoe produces a shoe of mysterious, randomly-selected color!
rpc MakeShoe(Size) returns (Shoe);
}

// Size of a Shoe, in inches.
message Size {
int32 inches = 1; // must be > 0
}

// A Shoe is a piece of footwear made by a Cobbler.
message Shoe {
int32 inches = 1;
string color = 2; // anything but "invisible"
string name = 3; // i.e. "oxford"
}

0 comments on commit 874cdfd

Please sign in to comment.