Open sirmyron opened 4 years ago
Gave this some more thought and I think "interceptors" may be a better name than "middleware" as it more aligns with how things work on the client side, particularly because we'd have to separate the request from the response.
Here's the proposal I have in mind for changes to the RPC call:
export const executeRpcCall = <TInput, TResult>(
apiUrl: string,
params: TInput,
opts: RpcOptions = {},
) => {
// ORIGINAL CODE, currently line 31 - 50
// NEW CODE, before serializing params
const {
headers: interceptedHeaders,
params: interceptedParams
} = invokeRequestInterceptorChain(headers, params, opts)
// optional safeguard
const updatedHeaders = interceptedHeaders || headers
const updatedParams = interceptedParams || params
// // ORIGINAL CODE, currently line 52
let serialized = serialize(updatedParams)
// ORIGINAL CODE
const promise = window
.fetch(apiUrl, {
method: "POST",
headers: updatedHeaders, // NEW CODE, currently line 69
credentials: "include",
redirect: "follow",
body: JSON.stringify({
params: serialized.json,
meta: {
params: serialized.meta,
},
}),
signal: controller.signal,
})
.then(async (result) => {
clientDebug("Received request for", apiUrl)
if (result.headers) {
// ORIGINAL CODE, currently line 81 - 119
throw error
} else {
// ORIGINAL CODE, currently line 123 - 131
// NEW CODE, currently line 132
const {
data: updatedData,
params: interceptedParams
} = invokeResponseInterceptorChain(headers, data)
return (updatedData || data) as TResult
}
}) as CancellablePromise<TResult>
// Disable react-query request cancellation for now
// Having too many weird bugs with it enabled
// promise.cancel = () => controller.abort()
return promise
}
Some additional points:
The thing left to figure out is how we get the handlers from the blitz.config.js and into the client side bundle.
What do you want and why?
I want to suggest supporting client-side middlewares (or maybe interceptors is a better way to think about it) that work in a similar way that the server middlewares do and allow you to modify requests/responses during the client-side useQuery executions.
My specific scenario is that I want to add a JWT token to requests that will be used in subsequent requests on the backend inside some queries/mutations.
Possible implementation(s)
The middlewares could be executed inside the rpc file that handles the client-side requests to the queries/mutations.
Additional context