Safe Haskell | None |
---|---|
Language | Haskell2010 |
Webhook Transformations are data transformations used to modify HTTP Requests/Responses before requests are executed and after responses are received.
Transformations are supplied by users as part of the Metadata for a
particular Action or EventTrigger as a RequestTransform
record. Per-field Transformations are stored as data
(defunctionalized), often in the form of a Kriti template, and then
converted into actual functions (reified) at runtime by the
Transform
typeclass.
We take a Higher Kinded Data (HKD) approach to representing the
transformations. RequestFields
is an HKD which can represent the
actual request data as 'RequestFields Identity' or the
defunctionalized transforms as 'RequestFields (WithOptional
TransformFn)'.
We can then traverse over the entire RequestFields
HKD to reify
all the fields at once and apply them to our actual request
data.
NOTE: We don't literally use traverse
or the HKD equivalent
btraverse
, but you can think of this operation morally as a
traversal. See applyRequestTransform
for implementation details.
Synopsis
- data RequestTransform = RequestTransform {}
- type RequestTransformFns = RequestFields (WithOptional TransformFn)
- type RequestData = RequestFields Identity
- data RequestFields f = RequestFields {
- method :: f Method
- url :: f Url
- body :: f Body
- queryParams :: f QueryParams
- requestHeaders :: f Headers
- requestL :: Lens' Request RequestData
- applyRequestTransform :: forall m. MonadError TransformErrorBundle m => (Request -> RequestTransformCtx) -> RequestTransformFns -> Request -> m Request
- newtype WithOptional f result = WithOptional {
- getOptional :: Maybe (f result)
- withOptional :: forall a b f. Coercible a (f b) => Maybe a -> WithOptional f b
- data ResponseTransform = ResponseTransform {}
- data MetadataResponseTransform = MetadataResponseTransform {}
- buildRespTransformCtx :: Maybe RequestTransformCtx -> Maybe SessionVariables -> TemplatingEngine -> ByteString -> ResponseTransformCtx
- mkRespTemplateTransform :: TemplatingEngine -> BodyTransformFn -> ResponseTransformCtx -> Either TransformErrorBundle Value
- mkResponseTransform :: MetadataResponseTransform -> ResponseTransform
- applyResponseTransform :: ResponseTransform -> ResponseTransformCtx -> Either TransformErrorBundle ByteString
Documentation
data RequestTransform Source #
RequestTransform
is the metadata representation of a request
transformation. It consists of a record of higher kinded data (HKD)
along with some regular data. We seperate the HKD data into its own
record field called requestFields
which we nest inside our
non-HKD record. The actual transformation operations are contained
in the HKD.
Instances
type RequestTransformFns = RequestFields (WithOptional TransformFn) Source #
Defunctionalized Webhook Transformation
We represent a defunctionalized request transformation by parameterizing
our HKD with WithOptional
TransformFn
, which marks each of the fields
as optional and supplies the appropriate transformation function to them if
if they are provided.
type RequestData = RequestFields Identity Source #
Actual Request Data
We represent the actual request data by parameterizing our HKD with
Identity
, which allows us to trivially unwrap the fields (which should
exist after any transformations have been applied).
data RequestFields f Source #
This is our HKD type. It is a record with fields for each
component of an Request
we wish to transform.
RequestFields | |
|
Instances
requestL :: Lens' Request RequestData Source #
A 'Lens'' for viewing a Request
as our RequestData
HKD; it does
so by wrapping each of the matching request fields in a corresponding
TransformFn
.
XXX: This function makes internal usage of decodeUtf8
, which throws an
impure exception when the supplied ByteString
cannot be decoded into valid
UTF8 text!
applyRequestTransform :: forall m. MonadError TransformErrorBundle m => (Request -> RequestTransformCtx) -> RequestTransformFns -> Request -> m Request Source #
Transform an Request
with a RequestTransform
.
Note: we pass in the request url explicitly for use in the
ReqTransformCtx
. We do this so that we can ensure that the url
is syntactically identical to what the use submits. If we use the
parsed request from the Request
term then it is possible
that the url is semantically equivalent but syntactically
different. An example of this is the presence or lack of a trailing
slash on the URL path. This important when performing string
interpolation on the request url.
newtype WithOptional f result Source #
Enrich a Functor
f
with optionality; this is primarily useful when
one wants to annotate fields as optional when using the Higher-Kinded Data
pattern.
WithOptional
f
is equivalent to Compose Maybe f
.
WithOptional | |
|
Instances
withOptional :: forall a b f. Coercible a (f b) => Maybe a -> WithOptional f b Source #
WithOptional
smart constructor for the special case of optional values
that are representationally equivalent to some "wrapper" type.
For example:
withOptional @HeaderTransformsAction headers == WithOptional $ fmap HeadersTransform headers
In other words: this function observes the isomorphism between
and Maybe
a
if an isomorphism exists between WithOptional
f ba
and f b
.
data ResponseTransform Source #
A set of data transformation functions generated from a
MetadataResponseTransform
. Nothing
means use the original
response value.
data MetadataResponseTransform Source #
Instances
buildRespTransformCtx :: Maybe RequestTransformCtx -> Maybe SessionVariables -> TemplatingEngine -> ByteString -> ResponseTransformCtx Source #
A helper function for constructing the RespTransformCtx
mkRespTemplateTransform :: TemplatingEngine -> BodyTransformFn -> ResponseTransformCtx -> Either TransformErrorBundle Value Source #
Construct a Template Transformation function for Responses
XXX: This function makes internal usage of decodeUtf8
, which throws an
impure exception when the supplied ByteString
cannot be decoded into valid
UTF8 text!
applyResponseTransform :: ResponseTransform -> ResponseTransformCtx -> Either TransformErrorBundle ByteString Source #
At the moment we only transform the body of
Responses. 'http-client' does not export the constructors for
Response
. If we want to transform then we will need additional
apply
functions.