ServerInterceptor.swift 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. * Copyright 2023, 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. /// A type that intercepts requests and response for server.
  17. ///
  18. /// Interceptors allow you to inspect and modify requests and responses. Requests are intercepted
  19. /// after they have been received by the transport and responses are intercepted after they have
  20. /// been returned from a service. They are typically used for cross-cutting concerns like filtering
  21. /// requests, validating messages, logging additional data, and tracing.
  22. ///
  23. /// Interceptors can be registered with the server either directly or via ``ConditionalInterceptor``s.
  24. /// You may register them for all services registered with a server, for RPCs directed to specific services, or
  25. /// for RPCs directed to specific methods. If you need to modify the behavior of an interceptor on a
  26. /// per-RPC basis in more detail, then you can use the ``ServerContext/descriptor`` to determine
  27. /// which RPC is being called and conditionalise behavior accordingly.
  28. ///
  29. /// ## RPC filtering
  30. ///
  31. /// A common use of server-side interceptors is to filter requests from clients. Interceptors can
  32. /// reject requests which are invalid without service code being called. The following example
  33. /// demonstrates this.
  34. ///
  35. /// ```swift
  36. /// struct AuthServerInterceptor: ServerInterceptor {
  37. /// let isAuthorized: @Sendable (String, MethodDescriptor) async throws -> Void
  38. ///
  39. /// func intercept<Input: Sendable, Output: Sendable>(
  40. /// request: StreamingServerRequest<Input>,
  41. /// context: ServerContext,
  42. /// next: @Sendable (
  43. /// _ request: StreamingServerRequest<Input>,
  44. /// _ context: ServerContext
  45. /// ) async throws -> StreamingServerResponse<Output>
  46. /// ) async throws -> StreamingServerResponse<Output> {
  47. /// // Extract the auth token.
  48. /// guard let token = request.metadata[stringValues: "authorization"].first(where: { _ in true }) else {
  49. /// throw RPCError(code: .unauthenticated, message: "Not authenticated")
  50. /// }
  51. ///
  52. /// // Check whether it's valid.
  53. /// try await self.isAuthorized(token, context.descriptor)
  54. ///
  55. /// // Forward the request.
  56. /// return try await next(request, context)
  57. /// }
  58. /// }
  59. /// ```
  60. ///
  61. /// For client-side interceptors see ``ClientInterceptor``.
  62. @available(gRPCSwift 2.0, *)
  63. public protocol ServerInterceptor: Sendable {
  64. /// Intercept a request object.
  65. ///
  66. /// - Parameters:
  67. /// - request: The request object.
  68. /// - context: Additional context about the request, including a descriptor
  69. /// of the method being called.
  70. /// - next: A closure to invoke to hand off the request and context to the next
  71. /// interceptor in the chain.
  72. /// - Returns: A response object.
  73. func intercept<Input: Sendable, Output: Sendable>(
  74. request: StreamingServerRequest<Input>,
  75. context: ServerContext,
  76. next: @Sendable (
  77. _ request: StreamingServerRequest<Input>,
  78. _ context: ServerContext
  79. ) async throws -> StreamingServerResponse<Output>
  80. ) async throws -> StreamingServerResponse<Output>
  81. }