protocol-grpc 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/context/getting-started.md +132 -0
- data/context/index.yaml +12 -0
- data/design.md +1675 -0
- data/lib/protocol/grpc/body/readable_body.rb +165 -0
- data/lib/protocol/grpc/body/writable_body.rb +101 -0
- data/lib/protocol/grpc/call.rb +64 -0
- data/lib/protocol/grpc/error.rb +133 -0
- data/lib/protocol/grpc/header.rb +119 -0
- data/lib/protocol/grpc/health_check.rb +19 -0
- data/lib/protocol/grpc/interface.rb +89 -0
- data/lib/protocol/grpc/metadata.rb +117 -0
- data/lib/protocol/grpc/methods.rb +113 -0
- data/lib/protocol/grpc/middleware.rb +71 -0
- data/lib/protocol/grpc/status.rb +50 -0
- data/lib/protocol/grpc/version.rb +12 -0
- data/lib/protocol/grpc.rb +35 -0
- data/license.md +21 -0
- data/readme.md +57 -0
- data/releases.md +5 -0
- metadata +114 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 27870f6774a55a9ea77ac67685009adc591273272ba29dc43a41d9362c32d933
|
|
4
|
+
data.tar.gz: 754b918b3865e479cbf853c2d0f4e3e7b8a5041e00ff95e6bc14f91a15341836
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 686459772400743ad026f2ea4ee001e3967ce2e5d584ba041cb1edf5a25200c77893dd919b70e90984f340b8008eb6d2c7faca70731c67c46bd4665915ae4f68
|
|
7
|
+
data.tar.gz: d1c6c68e07e91936ce968e15a942ca2c77dd5229d32d8eb778d351e8e19e6d52056bd9752abdb4757f2acfec810fc0f9216d6fa33ac6dc190ebe1a47c391513b
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Getting Started
|
|
2
|
+
|
|
3
|
+
This guide explains how to use `protocol-grpc` for building abstract gRPC interfaces.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add the gem to your project:
|
|
8
|
+
|
|
9
|
+
~~~ bash
|
|
10
|
+
$ bundle add protocol-grpc
|
|
11
|
+
~~~
|
|
12
|
+
|
|
13
|
+
## Core Concepts
|
|
14
|
+
|
|
15
|
+
`protocol-grpc` has several core concepts:
|
|
16
|
+
|
|
17
|
+
- A {ruby Protocol::GRPC::Interface} class which defines gRPC service contracts with RPC methods, request/response types, and streaming patterns.
|
|
18
|
+
- A {ruby Protocol::GRPC::Body::ReadableBody} class which handles reading gRPC messages from HTTP request/response bodies with automatic framing and decoding.
|
|
19
|
+
- A {ruby Protocol::GRPC::Body::WritableBody} class which handles writing gRPC messages to HTTP request/response bodies with automatic framing and encoding.
|
|
20
|
+
- A {ruby Protocol::GRPC::Middleware} abstract base class for building gRPC server applications.
|
|
21
|
+
- A {ruby Protocol::GRPC::Call} class which represents the context of a single gRPC RPC call, including deadline tracking.
|
|
22
|
+
- A {ruby Protocol::GRPC::Status} module with gRPC status code constants.
|
|
23
|
+
- A {ruby Protocol::GRPC::Error} hierarchy for gRPC-specific error handling.
|
|
24
|
+
|
|
25
|
+
## Integration
|
|
26
|
+
|
|
27
|
+
This gem provides protocol-level abstractions only. To actually send requests over the network, you need an HTTP/2 client/server implementation:
|
|
28
|
+
|
|
29
|
+
- [Async::GRPC](https://github.com/socketry/async-grpc) which provides asynchronous client and server implementations.
|
|
30
|
+
- [Async::HTTP](https://github.com/socketry/async-http) which provides HTTP/2 transport with connection pooling and concurrency.
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
### Defining an Interface
|
|
35
|
+
|
|
36
|
+
{ruby Protocol::GRPC::Interface} defines the contract for gRPC services. RPC method names use PascalCase to match `.proto` files:
|
|
37
|
+
|
|
38
|
+
``` ruby
|
|
39
|
+
require "protocol/grpc/interface"
|
|
40
|
+
|
|
41
|
+
class GreeterInterface < Protocol::GRPC::Interface
|
|
42
|
+
rpc :SayHello, request_class: Hello::HelloRequest, response_class: Hello::HelloReply
|
|
43
|
+
rpc :SayHelloAgain, request_class: Hello::HelloRequest, response_class: Hello::HelloReply,
|
|
44
|
+
streaming: :server_streaming
|
|
45
|
+
end
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Building a Request
|
|
49
|
+
|
|
50
|
+
Build gRPC requests using `Protocol::GRPC::Methods` and `Protocol::GRPC::Body::WritableBody`:
|
|
51
|
+
|
|
52
|
+
``` ruby
|
|
53
|
+
require "protocol/grpc"
|
|
54
|
+
require "protocol/grpc/methods"
|
|
55
|
+
require "protocol/grpc/body/writable_body"
|
|
56
|
+
|
|
57
|
+
# Build request body
|
|
58
|
+
body = Protocol::GRPC::Body::WritableBody.new(message_class: Hello::HelloRequest)
|
|
59
|
+
body.write(Hello::HelloRequest.new(name: "World"))
|
|
60
|
+
body.close_write
|
|
61
|
+
|
|
62
|
+
# Build headers
|
|
63
|
+
headers = Protocol::GRPC::Methods.build_headers(timeout: 5.0)
|
|
64
|
+
path = Protocol::GRPC::Methods.build_path("hello.Greeter", "SayHello")
|
|
65
|
+
|
|
66
|
+
# Create HTTP request
|
|
67
|
+
request = Protocol::HTTP::Request["POST", path, headers, body]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Reading a Response
|
|
71
|
+
|
|
72
|
+
Read gRPC responses using `Protocol::GRPC::Body::ReadableBody`:
|
|
73
|
+
|
|
74
|
+
``` ruby
|
|
75
|
+
require "protocol/grpc/body/readable_body"
|
|
76
|
+
|
|
77
|
+
# Read response body
|
|
78
|
+
readable_body = Protocol::GRPC::Body::ReadableBody.new(
|
|
79
|
+
response.body,
|
|
80
|
+
message_class: Hello::HelloReply
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
message = readable_body.read
|
|
84
|
+
readable_body.close
|
|
85
|
+
|
|
86
|
+
# Check gRPC status
|
|
87
|
+
status = Protocol::GRPC::Metadata.extract_status(response.headers)
|
|
88
|
+
if status != Protocol::GRPC::Status::OK
|
|
89
|
+
message = Protocol::GRPC::Metadata.extract_message(response.headers)
|
|
90
|
+
raise Protocol::GRPC::Error.for(status, message)
|
|
91
|
+
end
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Server Middleware
|
|
95
|
+
|
|
96
|
+
Create a server middleware by subclassing `Protocol::GRPC::Middleware`:
|
|
97
|
+
|
|
98
|
+
``` ruby
|
|
99
|
+
require "protocol/grpc/middleware"
|
|
100
|
+
|
|
101
|
+
class MyMiddleware < Protocol::GRPC::Middleware
|
|
102
|
+
protected
|
|
103
|
+
|
|
104
|
+
def dispatch(request)
|
|
105
|
+
# Parse service and method from path
|
|
106
|
+
service_name, method_name = Protocol::GRPC::Methods.parse_path(request.path)
|
|
107
|
+
|
|
108
|
+
# Handle the request and return a response
|
|
109
|
+
# ...
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Call Context
|
|
115
|
+
|
|
116
|
+
{ruby Protocol::GRPC::Call} provides context for a gRPC call:
|
|
117
|
+
|
|
118
|
+
``` ruby
|
|
119
|
+
require "protocol/grpc/call"
|
|
120
|
+
|
|
121
|
+
call = Protocol::GRPC::Call.new(request, deadline: deadline)
|
|
122
|
+
|
|
123
|
+
# Access request
|
|
124
|
+
call.request # => Protocol::HTTP::Request
|
|
125
|
+
|
|
126
|
+
# Check deadline
|
|
127
|
+
call.deadline.exceeded? # => false
|
|
128
|
+
|
|
129
|
+
# Access peer information
|
|
130
|
+
call.peer # => Protocol::HTTP::Address
|
|
131
|
+
```
|
|
132
|
+
|
data/context/index.yaml
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Automatically generated context index for Utopia::Project guides.
|
|
2
|
+
# Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
|
|
3
|
+
---
|
|
4
|
+
description: Protocol abstractions for gRPC, built on top of protocol-http.
|
|
5
|
+
metadata:
|
|
6
|
+
documentation_uri: https://socketry.github.io/protocol-grpc/
|
|
7
|
+
source_code_uri: https://github.com/socketry/protocol-grpc.git
|
|
8
|
+
files:
|
|
9
|
+
- path: getting-started.md
|
|
10
|
+
title: Getting Started
|
|
11
|
+
description: This guide explains how to use `protocol-grpc` for building abstract
|
|
12
|
+
gRPC interfaces.
|