Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Look for handlers in both the fully-qualified namespace, or root namespace. #18

Merged
merged 5 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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'
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"
}
Loading