mu-grpc-common 0.2.0.0 → 0.3.0.0
raw patch · 3 files changed
+70/−38 lines, 3 filesdep ~avrodep ~mu-avrodep ~mu-protobufPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: avro, mu-avro, mu-protobuf, mu-rpc, mu-schema
API changes (from Hackage documentation)
- Mu.GRpc.Avro: instance (Mu.Schema.Class.FromSchema Data.Functor.Identity.Identity sch sty i, Data.Avro.FromAvro.FromAvro (Mu.Schema.Interpretation.Term Data.Functor.Identity.Identity sch (sch Mu.Schema.Definition.:/: sty))) => Network.GRPC.HTTP2.Encoding.GRPCInput Mu.GRpc.Avro.AvroRPC (Mu.GRpc.Avro.ViaFromAvroTypeRef ('Mu.Rpc.ViaSchema sch sty) i)
- Mu.GRpc.Avro: instance (Mu.Schema.Class.FromSchema Data.Functor.Identity.Identity sch sty i, Data.Avro.FromAvro.FromAvro (Mu.Schema.Interpretation.Term Data.Functor.Identity.Identity sch (sch Mu.Schema.Definition.:/: sty))) => Network.GRPC.HTTP2.Encoding.GRPCOutput Mu.GRpc.Avro.AvroRPC (Mu.GRpc.Avro.ViaFromAvroTypeRef ('Mu.Rpc.ViaSchema sch sty) i)
- Mu.GRpc.Avro: instance (Mu.Schema.Class.ToSchema Data.Functor.Identity.Identity sch sty o, Data.Avro.ToAvro.ToAvro (Mu.Schema.Interpretation.Term Data.Functor.Identity.Identity sch (sch Mu.Schema.Definition.:/: sty))) => Network.GRPC.HTTP2.Encoding.GRPCInput Mu.GRpc.Avro.AvroRPC (Mu.GRpc.Avro.ViaToAvroTypeRef ('Mu.Rpc.ViaSchema sch sty) o)
- Mu.GRpc.Avro: instance (Mu.Schema.Class.ToSchema Data.Functor.Identity.Identity sch sty o, Data.Avro.ToAvro.ToAvro (Mu.Schema.Interpretation.Term Data.Functor.Identity.Identity sch (sch Mu.Schema.Definition.:/: sty))) => Network.GRPC.HTTP2.Encoding.GRPCOutput Mu.GRpc.Avro.AvroRPC (Mu.GRpc.Avro.ViaToAvroTypeRef ('Mu.Rpc.ViaSchema sch sty) o)
+ Mu.GRpc.Avro: instance (Data.Avro.HasAvroSchema.HasAvroSchema (Mu.Schema.Class.WithSchema sch sty i), Data.Avro.Encoding.FromAvro.FromAvro (Mu.Schema.Class.WithSchema sch sty i)) => Network.GRPC.HTTP2.Encoding.GRPCInput Mu.GRpc.Avro.AvroRPC (Mu.GRpc.Avro.ViaFromAvroTypeRef ('Mu.Rpc.SchemaRef sch sty) i)
+ Mu.GRpc.Avro: instance (Data.Avro.HasAvroSchema.HasAvroSchema (Mu.Schema.Class.WithSchema sch sty i), Data.Avro.Encoding.FromAvro.FromAvro (Mu.Schema.Class.WithSchema sch sty i)) => Network.GRPC.HTTP2.Encoding.GRPCOutput Mu.GRpc.Avro.AvroRPC (Mu.GRpc.Avro.ViaFromAvroTypeRef ('Mu.Rpc.SchemaRef sch sty) i)
+ Mu.GRpc.Avro: instance (Data.Avro.HasAvroSchema.HasAvroSchema (Mu.Schema.Class.WithSchema sch sty o), Data.Avro.Encoding.ToAvro.ToAvro (Mu.Schema.Class.WithSchema sch sty o)) => Network.GRPC.HTTP2.Encoding.GRPCInput Mu.GRpc.Avro.AvroRPC (Mu.GRpc.Avro.ViaToAvroTypeRef ('Mu.Rpc.SchemaRef sch sty) o)
+ Mu.GRpc.Avro: instance (Data.Avro.HasAvroSchema.HasAvroSchema (Mu.Schema.Class.WithSchema sch sty o), Data.Avro.Encoding.ToAvro.ToAvro (Mu.Schema.Class.WithSchema sch sty o)) => Network.GRPC.HTTP2.Encoding.GRPCOutput Mu.GRpc.Avro.AvroRPC (Mu.GRpc.Avro.ViaToAvroTypeRef ('Mu.Rpc.SchemaRef sch sty) o)
- Mu.GRpc.Avro: ViaFromAvroTypeRef :: t -> ViaFromAvroTypeRef (ref :: TypeRef) t
+ Mu.GRpc.Avro: ViaFromAvroTypeRef :: t -> ViaFromAvroTypeRef (ref :: TypeRef snm) t
- Mu.GRpc.Avro: ViaToAvroTypeRef :: t -> ViaToAvroTypeRef (ref :: TypeRef) t
+ Mu.GRpc.Avro: ViaToAvroTypeRef :: t -> ViaToAvroTypeRef (ref :: TypeRef snm) t
- Mu.GRpc.Avro: [unViaFromAvroTypeRef] :: ViaFromAvroTypeRef (ref :: TypeRef) t -> t
+ Mu.GRpc.Avro: [unViaFromAvroTypeRef] :: ViaFromAvroTypeRef (ref :: TypeRef snm) t -> t
- Mu.GRpc.Avro: [unViaToAvroTypeRef] :: ViaToAvroTypeRef (ref :: TypeRef) t -> t
+ Mu.GRpc.Avro: [unViaToAvroTypeRef] :: ViaToAvroTypeRef (ref :: TypeRef snm) t -> t
- Mu.GRpc.Avro: newtype ViaFromAvroTypeRef (ref :: TypeRef) t
+ Mu.GRpc.Avro: newtype ViaFromAvroTypeRef (ref :: TypeRef snm) t
- Mu.GRpc.Avro: newtype ViaToAvroTypeRef (ref :: TypeRef) t
+ Mu.GRpc.Avro: newtype ViaToAvroTypeRef (ref :: TypeRef snm) t
Files
- mu-grpc-common.cabal +9/−7
- src/Mu/GRpc/Avro.hs +43/−30
- src/Mu/GRpc/Bridge.hs +18/−1
mu-grpc-common.cabal view
@@ -1,7 +1,9 @@ name: mu-grpc-common-version: 0.2.0.0+version: 0.3.0.0 synopsis: gRPC for Mu, common modules for client and server-description: Use @mu-grpc-server@ or @mu-grpc-client@+description:+ Use @mu-grpc-server@ or @mu-grpc-client@ (the common parts).+ license: Apache-2.0 license-file: LICENSE author: Alejandro Serrano, Flavio Corpa@@ -23,16 +25,16 @@ Mu.GRpc.Bridge build-depends:- avro >=0.4.7+ avro >=0.5 , base >=4.12 && <5 , binary , bytestring , http2-grpc-proto3-wire , http2-grpc-types- , mu-avro >=0.2.0- , mu-protobuf >=0.2.0- , mu-rpc >=0.2.0- , mu-schema >=0.2.0+ , mu-avro >=0.3.0+ , mu-protobuf >=0.3.0+ , mu-rpc >=0.3.0+ , mu-schema >=0.3.0 hs-source-dirs: src default-language: Haskell2010
src/Mu/GRpc/Avro.hs view
@@ -2,14 +2,23 @@ {-# language DataKinds #-} {-# language FlexibleContexts #-} {-# language FlexibleInstances #-}-{-# language KindSignatures #-} {-# language MultiParamTypeClasses #-} {-# language OverloadedStrings #-}+{-# language PolyKinds #-} {-# language ScopedTypeVariables #-} {-# language TypeApplications #-} {-# language TypeOperators #-} {-# language UndecidableInstances #-}-{-# options_ghc -fno-warn-orphans #-}+{-# options_ghc -fno-warn-orphans -fno-warn-simplifiable-class-constraints #-}+{-|+Description : (Internal) Wrappers for Avro serialization++Intended for internal use.++This module provides the required instances of+the common type classes from 'Mu.GRpc.Bridge'+to make it work with Avro.+-} module Mu.GRpc.Avro ( AvroRPC(..) , ViaFromAvroTypeRef(..)@@ -23,7 +32,6 @@ import Data.ByteString.Char8 (ByteString) import qualified Data.ByteString.Char8 as ByteString import Data.ByteString.Lazy (fromStrict, toStrict)-import Data.Functor.Identity import Data.Kind import GHC.TypeLits import Network.GRPC.HTTP2.Encoding@@ -34,20 +42,27 @@ import Data.Monoid ((<>)) #endif -import Mu.Adapter.Avro ()+import Mu.Adapter.Avro () import Mu.Rpc import Mu.Schema -- | A proxy type for giving static information about RPCs.+-- Intended for internal use. data AvroRPC = AvroRPC { pkg :: ByteString, srv :: ByteString, meth :: ByteString } instance IsRPC AvroRPC where path rpc = "/" <> pkg rpc <> "." <> srv rpc <> "/" <> meth rpc {-# INLINE path #-} -newtype ViaFromAvroTypeRef (ref :: TypeRef) t+-- | Wrapper used to tag a type with its corresponding+-- 'TypeRef' used for deserialization from Avro.+-- Intended for internal use.+newtype ViaFromAvroTypeRef (ref :: TypeRef snm) t = ViaFromAvroTypeRef { unViaFromAvroTypeRef :: t }-newtype ViaToAvroTypeRef (ref :: TypeRef) t+-- | Wrapper used to tag a type with its corresponding+-- 'TypeRef' used for serialization to Avro.+-- Intended for internal use.+newtype ViaToAvroTypeRef (ref :: TypeRef snm) t = ViaToAvroTypeRef { unViaToAvroTypeRef :: t } instance GRPCInput AvroRPC () where@@ -59,54 +74,52 @@ decodeOutput _ _ = runGetIncremental $ pure $ Right () instance forall (sch :: Schema') (sty :: Symbol) (i :: Type).- ( FromSchema Identity sch sty i- , FromAvro (Term Identity sch (sch :/: sty)) )- => GRPCInput AvroRPC (ViaFromAvroTypeRef ('ViaSchema sch sty) i) where+ ( HasAvroSchema (WithSchema sch sty i)+ , FromAvro (WithSchema sch sty i) )+ => GRPCInput AvroRPC (ViaFromAvroTypeRef ('SchemaRef sch sty) i) where encodeInput = error "eif/you should not call this"- decodeInput _ i = (ViaFromAvroTypeRef . fromSchema' @_ @_ @sch @Identity <$>) <$> decoder i+ decodeInput _ i = (ViaFromAvroTypeRef . unWithSchema @_ @_ @sch @sty @i <$>) <$> decoder i instance forall (sch :: Schema') (sty :: Symbol) (i :: Type).- ( FromSchema Identity sch sty i- , FromAvro (Term Identity sch (sch :/: sty)) )- => GRPCOutput AvroRPC (ViaFromAvroTypeRef ('ViaSchema sch sty) i) where+ ( HasAvroSchema (WithSchema sch sty i)+ , FromAvro (WithSchema sch sty i) )+ => GRPCOutput AvroRPC (ViaFromAvroTypeRef ('SchemaRef sch sty) i) where encodeOutput = error "eof/you should not call this"- decodeOutput _ i = (ViaFromAvroTypeRef . fromSchema' @_ @_ @sch @Identity <$>) <$> decoder i+ decodeOutput _ i = (ViaFromAvroTypeRef . unWithSchema @_ @_ @sch @sty @i <$>) <$> decoder i instance forall (sch :: Schema') (sty :: Symbol) (o :: Type).- ( ToSchema Identity sch sty o- , ToAvro (Term Identity sch (sch :/: sty)) )- => GRPCInput AvroRPC (ViaToAvroTypeRef ('ViaSchema sch sty) o) where+ ( HasAvroSchema (WithSchema sch sty o)+ , ToAvro (WithSchema sch sty o) )+ => GRPCInput AvroRPC (ViaToAvroTypeRef ('SchemaRef sch sty) o) where encodeInput _ compression- = encoder compression . toSchema' @_ @_ @sch @Identity . unViaToAvroTypeRef+ = encoder compression . WithSchema @_ @_ @sch @sty . unViaToAvroTypeRef decodeInput = error "dit/you should not call this" instance forall (sch :: Schema') (sty :: Symbol) (o :: Type).- ( ToSchema Identity sch sty o- , ToAvro (Term Identity sch (sch :/: sty)) )- => GRPCOutput AvroRPC (ViaToAvroTypeRef ('ViaSchema sch sty) o) where+ ( HasAvroSchema (WithSchema sch sty o)+ , ToAvro (WithSchema sch sty o) )+ => GRPCOutput AvroRPC (ViaToAvroTypeRef ('SchemaRef sch sty) o) where encodeOutput _ compression- = encoder compression . toSchema' @_ @_ @sch @Identity . unViaToAvroTypeRef+ = encoder compression . WithSchema @_ @_ @sch @sty . unViaToAvroTypeRef decodeOutput = error "dot/you should not call this" -encoder :: ToAvro m => Compression -> m -> Builder+encoder :: (HasAvroSchema m, ToAvro m)+ => Compression -> m -> Builder encoder compression plain = mconcat [ singleton (if _compressionByteSet compression then 1 else 0) , putWord32be (fromIntegral $ ByteString.length bin) , fromByteString bin ] where- bin = _compressionFunction compression $ toStrict $ encode plain+ bin = _compressionFunction compression $ toStrict $ encodeValue plain -decoder :: FromAvro a => Compression -> Decoder (Either String a)+decoder :: (HasAvroSchema a, FromAvro a)+ => Compression -> Decoder (Either String a) decoder compression = runGetIncremental $ do isCompressed <- getInt8 -- 1byte let decompress = if isCompressed == 0 then pure else _decompressionFunction compression n <- getWord32be -- 4bytes- decode' . fromStrict <$> (decompress =<< getByteString (fromIntegral n))- where- decode' x = case decode x of- Success y -> Right y- Error e -> Left e+ decodeValue . fromStrict <$> (decompress =<< getByteString (fromIntegral n)) -- Based on https://hackage.haskell.org/package/binary/docs/Data-Binary-Get-Internal.html instance Functor Decoder where
src/Mu/GRpc/Bridge.hs view
@@ -5,6 +5,15 @@ {-# language PolyKinds #-} {-# language TypeFamilies #-} {-# language UndecidableInstances #-}+{-|+Description : Supported serialization formats for gRPC++Currently Protocol Buffers and Avro can be used as+serialization format for the messages in gRPC+requests and replies. This module provides types+and proxies used in both @mu-grpc-client@ and+@mu-grpc-server@ to drive this choice of serialization.+-} module Mu.GRpc.Bridge where import Data.ByteString@@ -14,15 +23,23 @@ import Mu.GRpc.Avro +-- | Serialization formats supported with gRPC. data GRpcMessageProtocol- = MsgProtoBuf | MsgAvro+ = MsgProtoBuf -- ^ Protocol Buffers.+ | MsgAvro -- ^ Avro. deriving (Eq, Show) +-- | Choose Protocol Buffers as serialization format for gRPC.+-- This value is commonly used to create a client or server. msgProtoBuf :: Proxy 'MsgProtoBuf msgProtoBuf = Proxy+-- | Choose Avro as serialization format for gRPC.+-- This value is commonly used to create a client or server. msgAvro :: Proxy 'MsgAvro msgAvro = Proxy +-- | Defines how to build serialization-specific+-- RPC locators from a triple of (package, server, method). class MkRPC (p :: GRpcMessageProtocol) where type RPCTy p :: Type mkRPC :: Proxy p -> ByteString -> ByteString -> ByteString -> RPCTy p