/src/grpc-swift/Sources/GRPC/GRPCClient.swift
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2019, gRPC Authors All rights reserved. |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | import NIOConcurrencyHelpers |
17 | | import NIOCore |
18 | | import NIOHTTP2 |
19 | | import SwiftProtobuf |
20 | | |
21 | | /// A gRPC client. |
22 | | public protocol GRPCClient: GRPCPreconcurrencySendable { |
23 | | /// The gRPC channel over which RPCs are sent and received. Note that this is distinct |
24 | | /// from `NIO.Channel`. |
25 | | var channel: GRPCChannel { get } |
26 | | |
27 | | /// The call options to use should the user not provide per-call options. |
28 | | var defaultCallOptions: CallOptions { get set } |
29 | | } |
30 | | |
31 | | // MARK: Convenience methods |
32 | | |
33 | | extension GRPCClient { |
34 | | public func makeUnaryCall<Request: SwiftProtobuf.Message, Response: SwiftProtobuf.Message>( |
35 | | path: String, |
36 | | request: Request, |
37 | | callOptions: CallOptions? = nil, |
38 | | interceptors: [ClientInterceptor<Request, Response>] = [], |
39 | | responseType: Response.Type = Response.self |
40 | 0 | ) -> UnaryCall<Request, Response> { |
41 | 0 | return self.channel.makeUnaryCall( |
42 | 0 | path: path, |
43 | 0 | request: request, |
44 | 0 | callOptions: callOptions ?? self.defaultCallOptions, |
45 | 0 | interceptors: interceptors |
46 | 0 | ) |
47 | 0 | } |
48 | | |
49 | | public func makeUnaryCall<Request: GRPCPayload, Response: GRPCPayload>( |
50 | | path: String, |
51 | | request: Request, |
52 | | callOptions: CallOptions? = nil, |
53 | | interceptors: [ClientInterceptor<Request, Response>] = [], |
54 | | responseType: Response.Type = Response.self |
55 | 0 | ) -> UnaryCall<Request, Response> { |
56 | 0 | return self.channel.makeUnaryCall( |
57 | 0 | path: path, |
58 | 0 | request: request, |
59 | 0 | callOptions: callOptions ?? self.defaultCallOptions, |
60 | 0 | interceptors: interceptors |
61 | 0 | ) |
62 | 0 | } |
63 | | |
64 | | public func makeServerStreamingCall< |
65 | | Request: SwiftProtobuf.Message, |
66 | | Response: SwiftProtobuf.Message |
67 | | >( |
68 | | path: String, |
69 | | request: Request, |
70 | | callOptions: CallOptions? = nil, |
71 | | interceptors: [ClientInterceptor<Request, Response>] = [], |
72 | | responseType: Response.Type = Response.self, |
73 | | handler: @escaping (Response) -> Void |
74 | 0 | ) -> ServerStreamingCall<Request, Response> { |
75 | 0 | return self.channel.makeServerStreamingCall( |
76 | 0 | path: path, |
77 | 0 | request: request, |
78 | 0 | callOptions: callOptions ?? self.defaultCallOptions, |
79 | 0 | interceptors: interceptors, |
80 | 0 | handler: handler |
81 | 0 | ) |
82 | 0 | } |
83 | | |
84 | | public func makeServerStreamingCall<Request: GRPCPayload, Response: GRPCPayload>( |
85 | | path: String, |
86 | | request: Request, |
87 | | callOptions: CallOptions? = nil, |
88 | | interceptors: [ClientInterceptor<Request, Response>] = [], |
89 | | responseType: Response.Type = Response.self, |
90 | | handler: @escaping (Response) -> Void |
91 | 0 | ) -> ServerStreamingCall<Request, Response> { |
92 | 0 | return self.channel.makeServerStreamingCall( |
93 | 0 | path: path, |
94 | 0 | request: request, |
95 | 0 | callOptions: callOptions ?? self.defaultCallOptions, |
96 | 0 | interceptors: interceptors, |
97 | 0 | handler: handler |
98 | 0 | ) |
99 | 0 | } |
100 | | |
101 | | public func makeClientStreamingCall< |
102 | | Request: SwiftProtobuf.Message, |
103 | | Response: SwiftProtobuf.Message |
104 | | >( |
105 | | path: String, |
106 | | callOptions: CallOptions? = nil, |
107 | | interceptors: [ClientInterceptor<Request, Response>] = [], |
108 | | requestType: Request.Type = Request.self, |
109 | | responseType: Response.Type = Response.self |
110 | 0 | ) -> ClientStreamingCall<Request, Response> { |
111 | 0 | return self.channel.makeClientStreamingCall( |
112 | 0 | path: path, |
113 | 0 | callOptions: callOptions ?? self.defaultCallOptions, |
114 | 0 | interceptors: interceptors |
115 | 0 | ) |
116 | 0 | } |
117 | | |
118 | | public func makeClientStreamingCall<Request: GRPCPayload, Response: GRPCPayload>( |
119 | | path: String, |
120 | | callOptions: CallOptions? = nil, |
121 | | interceptors: [ClientInterceptor<Request, Response>] = [], |
122 | | requestType: Request.Type = Request.self, |
123 | | responseType: Response.Type = Response.self |
124 | 0 | ) -> ClientStreamingCall<Request, Response> { |
125 | 0 | return self.channel.makeClientStreamingCall( |
126 | 0 | path: path, |
127 | 0 | callOptions: callOptions ?? self.defaultCallOptions, |
128 | 0 | interceptors: interceptors |
129 | 0 | ) |
130 | 0 | } |
131 | | |
132 | | public func makeBidirectionalStreamingCall< |
133 | | Request: SwiftProtobuf.Message, |
134 | | Response: SwiftProtobuf.Message |
135 | | >( |
136 | | path: String, |
137 | | callOptions: CallOptions? = nil, |
138 | | interceptors: [ClientInterceptor<Request, Response>] = [], |
139 | | requestType: Request.Type = Request.self, |
140 | | responseType: Response.Type = Response.self, |
141 | | handler: @escaping (Response) -> Void |
142 | 0 | ) -> BidirectionalStreamingCall<Request, Response> { |
143 | 0 | return self.channel.makeBidirectionalStreamingCall( |
144 | 0 | path: path, |
145 | 0 | callOptions: callOptions ?? self.defaultCallOptions, |
146 | 0 | interceptors: interceptors, |
147 | 0 | handler: handler |
148 | 0 | ) |
149 | 0 | } |
150 | | |
151 | | public func makeBidirectionalStreamingCall<Request: GRPCPayload, Response: GRPCPayload>( |
152 | | path: String, |
153 | | callOptions: CallOptions? = nil, |
154 | | interceptors: [ClientInterceptor<Request, Response>] = [], |
155 | | requestType: Request.Type = Request.self, |
156 | | responseType: Response.Type = Response.self, |
157 | | handler: @escaping (Response) -> Void |
158 | 0 | ) -> BidirectionalStreamingCall<Request, Response> { |
159 | 0 | return self.channel.makeBidirectionalStreamingCall( |
160 | 0 | path: path, |
161 | 0 | callOptions: callOptions ?? self.defaultCallOptions, |
162 | 0 | interceptors: interceptors, |
163 | 0 | handler: handler |
164 | 0 | ) |
165 | 0 | } |
166 | | } |
167 | | |
168 | | /// A client which has no generated stubs and may be used to create gRPC calls manually. |
169 | | /// See ``GRPCClient`` for details. |
170 | | /// |
171 | | /// Example: |
172 | | /// |
173 | | /// ``` |
174 | | /// let client = AnyServiceClient(channel: channel) |
175 | | /// let rpc: UnaryCall<Request, Response> = client.makeUnaryCall( |
176 | | /// path: "/serviceName/methodName", |
177 | | /// request: .with { ... }, |
178 | | /// } |
179 | | /// ``` |
180 | | @available(*, deprecated, renamed: "GRPCAnyServiceClient") |
181 | | public final class AnyServiceClient: GRPCClient { |
182 | 0 | private let lock = Lock() |
183 | | private var _defaultCallOptions: CallOptions |
184 | | |
185 | | /// The gRPC channel over which RPCs are sent and received. |
186 | | public let channel: GRPCChannel |
187 | | |
188 | | /// The default options passed to each RPC unless passed for each RPC. |
189 | | public var defaultCallOptions: CallOptions { |
190 | 0 | get { return self.lock.withLock { self._defaultCallOptions } } |
191 | 0 | set { self.lock.withLockVoid { self._defaultCallOptions = newValue } } |
192 | | } |
193 | | |
194 | | /// Creates a client which may be used to call any service. |
195 | | /// |
196 | | /// - Parameters: |
197 | | /// - connection: ``ClientConnection`` to the service host. |
198 | | /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. |
199 | 0 | public init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) { |
200 | 0 | self.channel = channel |
201 | 0 | self._defaultCallOptions = defaultCallOptions |
202 | 0 | } |
203 | | } |
204 | | |
205 | | // Unchecked because mutable state is protected by a lock. |
206 | | @available(*, deprecated, renamed: "GRPCAnyServiceClient") |
207 | | extension AnyServiceClient: @unchecked Sendable {} |
208 | | |
209 | | /// A client which has no generated stubs and may be used to create gRPC calls manually. |
210 | | /// See ``GRPCClient`` for details. |
211 | | /// |
212 | | /// Example: |
213 | | /// |
214 | | /// ``` |
215 | | /// let client = GRPCAnyServiceClient(channel: channel) |
216 | | /// let rpc: UnaryCall<Request, Response> = client.makeUnaryCall( |
217 | | /// path: "/serviceName/methodName", |
218 | | /// request: .with { ... }, |
219 | | /// } |
220 | | /// ``` |
221 | | public struct GRPCAnyServiceClient: GRPCClient { |
222 | | public let channel: GRPCChannel |
223 | | |
224 | | /// The default options passed to each RPC unless passed for each RPC. |
225 | | public var defaultCallOptions: CallOptions |
226 | | |
227 | | /// Creates a client which may be used to call any service. |
228 | | /// |
229 | | /// - Parameters: |
230 | | /// - connection: ``ClientConnection`` to the service host. |
231 | | /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. |
232 | 0 | public init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) { |
233 | 0 | self.channel = channel |
234 | 0 | self.defaultCallOptions = defaultCallOptions |
235 | 0 | } |
236 | | } |