HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Modulegrpc-spec-1.0.0Haskell2010

Network.GRPC.Spec

Pure implementation of the gRPC spec

Most code will not need to use this module directly.

Intended for unqualified import.

  • 68 types
  • 11 classes
  • 48 values
  • Packagegrpc-spec-1.0.0
  • Exports137
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceSpec.hs

RPC

6 declarations
classclass (NFData (Input rpc), NFData (Output rpc), Show (Input rpc), Show (Output rpc), Show (RequestMetadata rpc), Show (ResponseInitialMetadata rpc), Show (ResponseTrailingMetadata rpc)) => IsRPC (rpc :: k) where
#

Abstract definition of an RPC

Note on encoding: the gRPC specification does not say anything about text encoding issues for paths (service names and method names) or message types. The Protobuf compiler (by far the most common instantation of gRPC) does not allow for non-ASCII character at all ("interpreting non ascii codepoint"). We therefore punt on the encoding issue here, and use bytestrings. If applications want to use non-ASCII characters, they can choose their own encoding.

Methods

  • rpcContentType :: Proxy rpc -> ByteString

    Content-type

    gRPC is agnostic to the message format; the spec defines the Content-Type header as

    Content-Type →
      "content-type"
      "application/grpc"
      [("+proto" / "+json" / {custom})]

    defaultRpcContentType can be used in the case that the format (such as proto) is known.

    Note on terminology: throughout this codebase we avoid the terms "encoding" and "decoding", which can be ambiguous. Instead we use "serialize"/"deserialize" and "compress"/"decompress".

  • rpcServiceName :: HasCallStack => Proxy rpc -> ByteString

    Service name

    For Protobuf, this is the fully qualified service name.

  • rpcMethodName :: HasCallStack => Proxy rpc -> ByteString

    Method name

    For Protobuf, this is just the method name (no qualifier required).

  • rpcMessageType :: HasCallStack => Proxy rpc -> Maybe ByteString

    Message type, if specified

    This is used to set the (optional) grpc-message-type header. For Protobuf, this is the fully qualified message type.

Instances3IsRPC
familytype family Input (rpc :: k)
#

Messages from the client to the server

Instances2Input
familytype family Output (rpc :: k)
#

Messages from the server to the client

Instances2Output

Client-side RPC

Methods

  • rpcSerializeInput :: Proxy rpc -> Input rpc -> ByteString

    Serialize RPC input

    We don't ask for a builder here, but instead ask for the complete serialized form. gRPC insists that individual messages are length prefixed, so we must compute the full serialization in memory before we can send anything.

    We use the terms "serialize" and "deserialize" here, and "compress"/"decompress" for compression, rather than "encode"/"decode", which could refer to either process.

  • rpcDeserializeOutput :: Proxy rpc -> ByteString -> Either String (Output rpc)

    Deserialize RPC output

    Discussion of rpcDeserializeInput applies here, also.

Instances3SupportsClientRpc

Server-side RPC

Methods

Instances3SupportsServerRpc

Instances

Protobuf

datadata Protobuf serv (meth :: Symbol)
#

Protobuf RPC

This exists only as a type-level marker

Instances8IsRPC, SupportsClientRpc, SupportsServerRpc, HasStreamingType, SupportsStreamingType, Input, …
newtypenewtype Proto msg
#

Wrapper around Protobuf messages and Protobuf enums

Protobuf messages and enums behave differently to normal Haskell datatypes. Fields in messages always have defaults, enums can have unknown values, etc. We therefore mark them at the type-level with this Proto wrapper. Most of the time you can work with Proto values as if the wrapper is not there, because Proto msg inherits Message and Data.ProtoLens.Field HasField instances from msg. For example, you can create a 'Proto Point' value as

p = defMessage
      & #latitude  .~ ..
      & #longitude .~ ..

and access fields from such a value using

p ^. #latitude

as per usual.

One advantage of the Proto wrapper is that we can give blanket instances for all Protobuf messages; we use this to provide GHC.Records HasField and GHC.Records.Compat HasField instances. This means that you can also use OverloadedRecordDot to access fields

p.latitude

or even OverloadedRecordUpdate to set fields

p{latitude = ..}

Constructors

Instances17Bounded, Enum, Eq, Ord, Show, NFData, …
  • HasField (Proto rec) fldName fldType => HasField fldName (Proto rec) fldTypeDefined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • HasField (Proto rec) fldName fldType => HasField fldName (Proto rec) fldTypeDefined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • Bounded msg => Bounded (Proto msg)Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • Enum msg => Enum (Proto msg)Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • Eq msg => Eq (Proto msg)Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • Ord msg => Ord (Proto msg)Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • Show msg => Show (Proto msg)Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • NFData msg => NFData (Proto msg)Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • FieldDefault msg => FieldDefault (Proto msg)Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • Message msg => Message (Proto msg)Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • MessageEnum msg => MessageEnum (Proto msg)Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • (HasField rec fldName x, RewrapField (Describe x) x fldType) => HasField (Proto rec) fldName fldTypeDefined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • RewrapField ('MkFieldDesc 'LabelImplicit 'NotScalar) a (Proto a)Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • RewrapField ('MkFieldDesc 'LabelOptional 'NotScalar) (Maybe a) (Maybe (Proto a))Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • RewrapField ('MkFieldDesc 'LabelRepeated 'NotScalar) (Vector a) (Vector (Proto a))Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • RewrapField ('MkFieldDesc 'LabelRepeated 'NotScalar) [a] [Proto a]Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf
  • RewrapField ('MkFieldDesc 'LabelMap 'NotScalar) (Map k a) (Map k (Proto a))Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.Protobuf

JSON

datadata JsonRpc (serv :: Symbol) (meth :: Symbol)
#

gRPC using JSON as the message encoding

"JSON over gRPC" is a bit of an ambiguous phrase. It can be a very general term, simply meaning using an otherwise-unspecified JSON encoding, or it can refer to "Protobuf over JSON" (see https://protobuf.dev/programming-guides/proto3/#json). In this module we deal with the former, and don't deal with anything Protobuf-specific at all, nor do we rely on any of the infrastructure generated by the Protobuf compiler (in other words, there is no need to use protoc). See https://grpc.io/blog/grpc-with-json/ for a Java example of using gRPC with JSON without Protobuf.

In the absence of the infrastructure provided by protoc, you will need to manually provide Input and Output instances for each RPC you use. For example:

type Create   = JsonRpc KeyValueService "Create"
type Delete   = JsonRpc KeyValueService "Delete"
..

type instance Input  Create   = ..
type instance Output Create   = ..
type instance Input  Retrieve = ..
type instance Output Retrieve = ..
..

On the client, you will need ToJSON instances for inputs and FromJSON instances for outputs; on the server the situation is dual. You may find it convenient to use JsonObject (but this is certainly not required).

TODO: https://github.com/well-typed/grapesy/issues/166 We don't currently offer explicit support for "Protobuf JSON".

Instances4IsRPC, SupportsClientRpc, SupportsServerRpc, SupportsStreamingType
datadata JsonObject (a :: [(Symbol, Type)]) where
#

Convenient way to construct JSON values

Example:

type instance Input Create =
  JsonObject '[ '("key"   , Required Key)
              , '("value" , Required Value)
              ]

Constructors

Instances6Show, NFData, FromJSON, ToJSON
newtypenewtype Required a
#

Required field

Constructors

Instances4Show, NFData, DecodeFields, EncodeFields
newtypenewtype Optional a
#

Optional field

Maybe will be represented by the absence of the field in the object.

Constructors

Instances4Show, NFData, DecodeFields, EncodeFields
classclass DecodeFields (fs :: [(Symbol, Type)]) where
#

Auxiliary class used for the FromJSON instance for JsonObject

It is not possible (nor necessary) to define additional instances.

Instances3DecodeFields
classclass EncodeFields (fs :: [(Symbol, Type)]) where
#

Auxiliary class used for the ToJSON instance for JsonObject

It is not possible (nor necessary) to define additional instances.

Instances3EncodeFields

Raw

datadata RawRpc (serv :: Symbol) (meth :: Symbol)
#

Custom gRPC format

Usually gRPC runs over Protobuf, but it does not have to. RawRpc provides an alternative format, which does not use serialization/deserialization at all, just using raw bytestrings for messages. This is a non-standard format (which the gRPC specification explicitly permits).

Instances6IsRPC, SupportsClientRpc, SupportsServerRpc, SupportsStreamingType, Input, Output

Streaming types

3 declarations
datadata StreamingType
#
Instances6Bounded, Enum, Eq, Ord, Read, Show
classclass ValidStreamingType (styp :: StreamingType) where
#

Valid streaming types

Methods

Instances4ValidStreamingType

Link RPCs to streaming types

classclass ValidStreamingType styp => SupportsStreamingType (rpc :: k) (styp :: StreamingType)
#

This RPC supports the given streaming type

This is a weaker condition than HasStreamingType: some (non-Protobuf) RPCs may support more than one streaming type.

Instances3SupportsStreamingType

Handler type definition

datadata NextElem a
#

Is there a next element in a stream?

Constructors

Instances5Functor, Foldable, Traversable, Eq, Show
  • Functor NextElemDefined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.StreamType
  • Foldable NextElemDefined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.StreamType
  • Traversable NextElemDefined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.StreamType
  • Eq a => Eq (NextElem a)Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.StreamType
  • Show a => Show (NextElem a)Defined in grpc-spec-1.0.0 · Network.GRPC.Spec.RPC.StreamType
typetype Recv a = IO (NextElem a)
#

Receive a value

Nothing indicates no more values. Calling this function again after receiving Nothing is a bug.

typetype Positive (m :: k -> Type) a (b :: k) = a -> m b
#

Positive use of a

familytype family Handler (r :: HandlerRole) (s :: StreamingType) (m :: Type -> Type) (rpc :: k) where
#

Type of a handler

Equations

Handler newtype wrappers

Compression

7 declarations
datadata CompressionId
#

Compression ID

The gRPC specification defines

Content-Coding → "identity" / "gzip" / "deflate" / "snappy" / {custom}
Instances6Eq, Ord, Show, IsString, Generic, Rep
datadata Compression
#

Compression scheme

Constructors

Instances1Show
  • Show CompressionDefined in grpc-spec-1.0.0 · Network.GRPC.Spec.Compression

Message metadata

2 declarations
datadata OutboundMeta
#

Meta-information for outbound messages

Constructors

Instances5Show, Generic, NFData, Default, Rep

Requests

3 declarations
datadata RequestHeaders_ (f :: Type -> Type)
#

Full set of call parameters required to construct the RPC call

This is constructed internally; it is not part of the public API.

Constructors

Instances8Generic, Coerce, Traversable, Eq, Show, Rep, …

Request headers (without allowing for invalid headers)

NOTE: The HKD type

RequestHeaders_ Undecorated

means that each field of type HKD f a is simply of type a (that is, undecorated).

Parameters

valuecallTimeout :: CallParams rpc -> Maybe Timeout
#

Timeout

Tell the server that if the request cannot be completed within the specified amount of time, it should be aborted. If the timeout gets exceeded, a Network.GRPC.Common.GrpcDeadlineExceeded exception will be raised.

Pseudo-headers

datadata Path
#

Path

The gRPC spec specifies:

Path → ":path" "/" Service-Name "/" {method name} # But see note below.

Moreover, it says:

Path is case-sensitive. Some gRPC implementations may allow the Path format
shown above to be overridden, but this functionality is strongly
discouraged. gRPC does not go out of its way to break users that are using
this kind of override, but we do not actively support it, and some
functionality (e.g., service config support) will not work when the path is
not of the form shown above.

We don't support these non-standard paths at all.

Instances3Eq, Show, Hashable
  • Eq PathDefined in grpc-spec-1.0.0 · Network.GRPC.Spec.Headers.PseudoHeaders
  • Show PathDefined in grpc-spec-1.0.0 · Network.GRPC.Spec.Headers.PseudoHeaders
  • Hashable PathDefined in grpc-spec-1.0.0 · Network.GRPC.Spec.Headers.PseudoHeaders
datadata Address
#

Address

The address of a server to connect to. This is not standard gRPC nomenclature, but follows convention such as adopted by grpcurl and grpc-client-cli, which distinguish between the address of a server to connect to (hostname and port), and the (optional) HTTP authority, which is an (optional) string to be included as the HTTP2 :authority pseudo-header.

Constructors

  • Address
    • addressHost :: HostName

      Hostname

    • addressPort :: PortNumber

      TCP port

    • addressAuthority :: Maybe String

      Authority

      When the authority is not specified, it defaults to addressHost.

      This is used both for the HTTP2 :authority pseudo-header as well as for TLS SNI (if using a secure connection).

      Although the HTTP(2) specification allows the authority to include a port number, and many servers can accept this, this will not work with TLS, and it is therefore recommended not to include a port number. Note that the HTTP2 spec explicitly disallows the authority to include userinfo@.

Instances1Show
  • Show AddressDefined in grpc-spec-1.0.0 · Network.GRPC.Spec.Headers.PseudoHeaders

Timeouts

datadata Timeout
#

Timeout

Instances4Eq, Show, Generic, Rep
newtypenewtype TimeoutValue
#

Positive integer with ASCII representation of at most 8 digits

Instances4Eq, Show, Generic, Rep
datadata TimeoutUnit
#

Timeout unit

Constructors

Instances4Eq, Show, Generic, Rep

Translate Timeout to microseconds

For Nanosecond timeout we round up.

Note: the choice of Integer for the result is important: timeouts can be quite long, and might easily exceed the range of a 32-bit int: 2^31 microseconds is roughly 35 minutes (on 64-bit architectures this is much less important; 2^63 microseconds is 292,277.2 years). We could use Int64 or Word64, but Integer works nicely with the unbounded-delays package.

Responses

0 declarations

Headers

datadata ResponseHeaders_ (f :: Type -> Type)
#

Response headers

Constructors

Instances8Generic, Coerce, Traversable, Eq, Show, Rep, …

Trailers

datadata ProperTrailers_ (f :: Type -> Type)
#

Information sent by the peer after the final output

Response trailers are a HTTP2 concept: they are HTTP headers that are sent after the content body. For example, imagine the server is streaming a file that it's reading from disk; it could use trailers to give the client an MD5 checksum when streaming is complete.

Constructors

Instances8Generic, Coerce, Traversable, Eq, Show, Rep, …

Trailers sent after the response, allowing for invalid trailers

We do not parameterize this over the type of synthesized errors: unlike response (or request) headers, we have no opportunity to check the trailers for synthesized errors ahead of time, so having a type to signal "trailers without synthesized errors" is not particularly useful.

datadata TrailersOnly_ (f :: Type -> Type)
#

Trailers sent in the gRPC Trailers-Only case

We deal with the HTTP status elsewhere.

Constructors

Instances8Generic, Coerce, Traversable, Eq, Show, Rep, …
datadata Pushback
#

Pushback

The server adds this header to push back against client retries. We do not yet support automatic retries (https://github.com/well-typed/grapesy/issues/104), but do we parse this header so that if the server includes it, we do not throw a parser error.

See also https://github.com/grpc/proposal/blob/master/A6-client-retries.md

Instances4Eq, Show, Generic, Rep

Termination

Status

2 declarations
datadata GrpcStatus
#
Instances4Eq, Show, Generic, Rep
datadata GrpcError
#

gRPC error code

This is a subset of the gRPC status codes. See GrpcStatus.

Constructors

  • GrpcCancelled

    Cancelled

    The operation was cancelled, typically by the caller.

  • GrpcUnknown

    Unknown error

    For example, this error may be returned when a Status value received from another address space belongs to an error space that is not known in this address space. Also errors raised by APIs that do not return enough error information may be converted to this error.

  • GrpcInvalidArgument

    Invalid argument

    The client specified an invalid argument. Note that this differs from GrpcFailedPrecondition: GrpcInvalidArgument indicates arguments that are problematic regardless of the state of the system (e.g., a malformed file name).

  • GrpcDeadlineExceeded

    Deadline exceeded

    The deadline expired before the operation could complete. For operations that change the state of the system, this error may be returned even if the operation has completed successfully. For example, a successful response from a server could have been delayed long.

  • GrpcNotFound

    Not found

    Some requested entity (e.g., file or directory) was not found.

    Note to server developers: if a request is denied for an entire class of users, such as gradual feature rollout or undocumented allowlist, GrpcNotFound may be used.

    If a request is denied for some users within a class of users, such as user-based access control, GrpcPermissionDenied must be used.

  • GrpcAlreadyExists

    Already exists

    The entity that a client attempted to create (e.g., file or directory) already exists.

  • GrpcPermissionDenied

    Permission denied

    The caller does not have permission to execute the specified operation.

    This error code does not imply the request is valid or the requested entity exists or satisfies other pre-conditions.

  • GrpcResourceExhausted

    Resource exhausted

    Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space.

  • GrpcFailedPrecondition

    Failed precondition

    The operation was rejected because the system is not in a state required for the operation's execution. For example, the directory to be deleted is non-empty, an rmdir operation is applied to a non-directory, etc.

    Service implementors can use the following guidelines to decide between GrpcFailedPrecondition, GrpcAborted, and GrpcUnavailable:

    (a) Use GrpcUnavailable if the client can retry just the failing call. (b) Use GrpcAborted if the client should retry at a higher level (e.g., when a client-specified test-and-set fails, indicating the client should restart a read-modify-write sequence). (c) Use GrpcFailedPrecondition if the client should not retry until the system state has been explicitly fixed. E.g., if an rmdir fails because the directory is non-empty, GrpcFailedPrecondition should be returned since the client should not retry unless the files are deleted from the directory.

  • GrpcAborted

    Aborted

    The operation was aborted, typically due to a concurrency issue such as a sequencer check failure or transaction abort. See the guidelines above for deciding between GrpcFailedPrecondition, GrpcAborted, and GrpcUnavailable.

  • GrpcOutOfRange

    Out of range

    The operation was attempted past the valid range. E.g., seeking or reading past end-of-file.

    Unlike GrpcInvalidArgument, this error indicates a problem that may be fixed if the system state changes. For example, a 32-bit file system will generate GrpcInvalidArgument if asked to read at an offset that is not in the range [0, 2^32-1], but it will generate GrpcOutOfRange if asked to read from an offset past the current file size.

    There is a fair bit of overlap between GrpcFailedPrecondition and GrpcOutOfRange. We recommend using GrpcOutOfRange (the more specific error) when it applies so that callers who are iterating through a space can easily look for an GrpcOutOfRange error to detect when they are done.

  • GrpcUnimplemented

    Unimplemented

    The operation is not implemented or is not supported/enabled in this service.

  • GrpcInternal

    Internal errors

    This means that some invariants expected by the underlying system have been broken. This error code is reserved for serious errors.

  • GrpcUnavailable

    Unavailable

    The service is currently unavailable. This is most likely a transient condition, which can be corrected by retrying with a backoff. Note that it is not always safe to retry non-idempotent operations.

  • GrpcDataLoss

    Data loss

    Unrecoverable data loss or corruption.

  • GrpcUnauthenticated

    Unauthenticated

    The request does not have valid authentication credentials for the operation.

Instances6Eq, Ord, Show, Generic, Exception, Rep

Numerical status codes

Exceptions

datadata GrpcException
#

Server indicated a gRPC error

For the common case where you just want to set grpcError, you can use throwGrpcError.

Instances3Eq, Show, Exception

Details

datadata Status
#

Fields :

  • Proto.Status_Fields.code :: Lens' Status Data.Int.Int32

  • Proto.Status_Fields.message :: Lens' Status Data.Text.Text

  • Proto.Status_Fields.details :: Lens' Status [Proto.Google.Protobuf.Any.Any]

  • Proto.Status_Fields.vec'details :: Lens' Status (Data.Vector.Vector Proto.Google.Protobuf.Any.Any)

Instances9Eq, Ord, Show, NFData, Message, HasField, …

Metadata

12 declarations
datadata CustomMetadata
#

Custom metadata

This is an arbitrary set of key-value pairs defined by the application layer.

Custom metadata order is not guaranteed to be preserved except for values with duplicate header names. Duplicate header names may have their values joined with "," as the delimiter and be considered semantically equivalent.

Instances5Eq, Show, Generic, NFData, Rep
datadata HeaderName
#

Header name

To construct a HeaderName, you can either use the IsString instance

"foo"     :: HeaderName -- an ASCII header
"bar-bin" :: HeaderName -- a binary header

or alternatively use the AsciiHeader and BinaryHeader patterns

AsciiHeader  "foo"
BinaryHeader "bar-bin"

The latter style is more explicit, and can catch more errors:

AsciiHeader  "foo-bin" -- exception: unexpected -bin suffix
BinaryHeader "bar"     -- exception: expected   -bin suffix

Header names cannot be empty, and must consist of digits (0-9), lowercase letters (a-z), underscore (_), hyphen (-), or period (.). Reserved header names are disallowed.

See also safeHeaderName.

Instances7Eq, Ord, Show, IsString, Generic, NFData, …

Check for valid ASCII header value

ASCII-Value → 1*( %x20-%x7E ) ; space and printable ASCII

NOTE: By rights this should verify that the header is non-empty. However, empty header values do occasionally show up, and so we permit them. The main reason for checking for validity at all is to ensure that we don't confuse binary headers and ASCII headers.

datadata NoMetadata
#

Indicate the absence of custom metadata

NOTE: The ParseMetadata instance for NoMetadata throws an exception if any metadata is present (that is, metadata is not silently ignored).

Instances6Eq, Show, Default, BuildMetadata, ParseMetadata, StaticMetadata

Handling of duplicate metadata entries

newtypenewtype CustomMetadataMap
#

Map from header names to values

The gRPC spec mandates

Custom-Metadata header order is not guaranteed to be preserved except for
values with duplicate header names. Duplicate header names may have their
values joined with "," as the delimiter and be considered semantically
equivalent.

Internally we don't allow for these duplicates, but instead join the headers as mandated by the spec.

Instances6Eq, Show, Generic, Semigroup, Monoid, Rep

Typed

familytype family RequestMetadata (rpc :: k)
#

Metadata included in the request

Often you can give a blanket metadata definition for all methods in a service. For example:

type instance RequestMetadata          (Protobuf RouteGuide meth) = NoMetadata
type instance ResponseInitialMetadata  (Protobuf RouteGuide meth) = NoMetadata
type instance ResponseTrailingMetadata (Protobuf RouteGuide meth) = NoMetadata

If you want to give specific types of metadata for specific methods but not for others, it can sometimes be useful to introduce an auxiliary closed type, so that you can give a catch-all case. For example:

type instance ResponseInitialMetadata (Protobuf Greeter meth) = GreeterResponseInitialMetadata meth

type family GreeterResponseInitialMetadata (meth :: Symbol) where
  GreeterResponseInitialMetadata "sayHelloStreamReply" = SayHelloMetadata
  GreeterResponseInitialMetadata meth                  = NoMetadata
datadata ResponseMetadata (rpc :: k)
#

Response metadata

It occassionally happens that we do not know if we should expect the initial metadata from the server or the trailing metadata (when the server uses Trailers-Only); for example, see Network.GRPC.Client.recvResponseInitialMetadata.

Instances2Eq, Show

Serialization

classclass ParseMetadata a where
#

Parse metadata from custom metadata headers

Some guidelines for defining instances:

  • You can assume that the list of headers will not contain duplicates. The gRPC spec does allow for duplicate headers and specifies how to process them, but this will be taken care of before parseMetadata is called.

  • However, you should assume no particular order.

  • If there are unexpected headers present, you have a choice whether you want to consider this a error and throw an exception, or regard the additional headers as merely additional information and simply ignore them. There is no single right answer here: ignoring additional metadata runs the risk of not realizing that the peer is trying to tell you something important, but throwing an error runs the risk of unnecessarily aborting an RPC.

Methods

Instances1ParseMetadata
classclass BuildMetadata a => StaticMetadata a where
#

Metadata with statically known fields

This is required for the response trailing metadata. When the server sends the initial set of headers to the client, it must tell the client which trailers to expect (by means of the HTTP Trailer header; see https://datatracker.ietf.org/doc/html/rfc7230#section-4.4).

Any headers constructed in buildMetadata must be listed here; not doing so is a bug. However, the converse is not true: it is acceptable for a header to be listed in metadataHeaderNames but not in buildMetadata. Put another way: the list of "trailers to expect" included in the initial request headers is allowed to be an overapproximation, but not an underapproximation.

Instances1StaticMetadata

Invalid headers

2 declarations
newtypenewtype InvalidHeaders e
#

Invalid headers

This is used for request headers, response headers, and response trailers.

Instances6Eq, Show, Semigroup, Monoid
datadata InvalidHeader e
#

Invalid header

This corresponds to a single "raw" HTTP header. It is possible that a particular field of, say, RequestHeaders corresponds to multiple InvalidHeader, when the value of that field is determined by combining multiple HTTP headers. A special case of this is the field for unrecognized headers (see requestUnrecognized, responseUnrecognized, etc.), which collects all unrecognized headers in one field (and has value () if there are none).

For some invalid headers the gRPC spec mandates a specific HTTP status; if this status is not specified, then we use 400 Bad Request.

Constructors

Instances2Eq, Show

Construction

Synthesized errors

datadata HandledSynthesized
#

Indicate that all synthesized errors have been handled

For some headers the gRPC spec mandates a specific gRPC error that should be synthesized when the header is invalid. We use HandledSynthesized in types to indicate that all errors that should have been synthesized have already been thrown.

For example, RequestHeaders' HandledSynthesized indicates that these request headers may still contain errors for some headers, but no errors for which the spec mandates that we synthesize a specific gRPC exception.

Instances2Eq, Show

Use

Common infrastructure to all headers

4 declarations
datadata ContentType
#

Content type

Constructors

Instances5Eq, Show, Generic, Default, Rep
datadata MessageType
#

Message type

Constructors

Instances5Eq, Show, Generic, Default, Rep

OpenTelemetry

4 declarations
datadata TraceContext
#

Trace context

Representation of the "trace context" in OpenTelemetry, corresponding directly to the W3C traceparent header.

References:

Relation to Haskell OpenTelemetry implementations:

  • The Haskell opentelemetry package calls this a SpanContext, but provides no binary PropagationFormat, and does not support TraceOptions.

https://hackage.haskell.org/package/opentelemetry

  • The Haskell hs-opentelemetry ecosystem defines SpanContext, which is the combination of the W3C traceparent header (our TraceContext) and the W3C tracestate header (which we do not support). It too does not support the grpc-trace-bin binary format.

https://github.com/iand675/hs-opentelemetry https://hackage.haskell.org/package/hs-opentelemetry-propagator-w3c

Instances6Eq, Show, Generic, Binary, Default, Rep
newtypenewtype TraceId
#

Trace ID

The ID of the whole trace forest. Must be a 16-byte string.

Instances6Eq, Show, IsString, Generic, Binary, Rep
newtypenewtype SpanId
#

Span ID

ID of the caller span (parent). Must be an 8-byte string.

Instances6Eq, Show, IsString, Generic, Binary, Rep
datadata TraceOptions
#

Tracing options

The flags are recommendations given by the caller rather than strict rules to follow for 3 reasons:

  • Trust and abuse.

  • Bug in caller

  • Different load between caller service and callee service might force callee to down sample.

Constructors

Instances5Eq, Show, Generic, Binary, Rep

ORCA

1 declaration
datadata OrcaLoadReport
#

Fields :

  • Proto.OrcaLoadReport_Fields.cpuUtilization :: Lens' OrcaLoadReport Prelude.Double

  • Proto.OrcaLoadReport_Fields.memUtilization :: Lens' OrcaLoadReport Prelude.Double

  • Proto.OrcaLoadReport_Fields.rps :: Lens' OrcaLoadReport Data.Word.Word64

  • Proto.OrcaLoadReport_Fields.requestCost :: Lens' OrcaLoadReport (Data.Map.Map Data.Text.Text Prelude.Double)

  • Proto.OrcaLoadReport_Fields.utilization :: Lens' OrcaLoadReport (Data.Map.Map Data.Text.Text Prelude.Double)

  • Proto.OrcaLoadReport_Fields.rpsFractional :: Lens' OrcaLoadReport Prelude.Double

  • Proto.OrcaLoadReport_Fields.eps :: Lens' OrcaLoadReport Prelude.Double

  • Proto.OrcaLoadReport_Fields.namedMetrics :: Lens' OrcaLoadReport (Data.Map.Map Data.Text.Text Prelude.Double)

  • Proto.OrcaLoadReport_Fields.applicationUtilization :: Lens' OrcaLoadReport Prelude.Double

Instances14Eq, Ord, Show, NFData, Message, HasField, …