diff --git a/architecture/MIDDLEWARE.MD b/architecture/MIDDLEWARE.MD index 034d1cf..ec5389b 100644 --- a/architecture/MIDDLEWARE.MD +++ b/architecture/MIDDLEWARE.MD @@ -20,49 +20,51 @@ Any modifications that the middleware function makes to the request or response The earlier the middleware is instantiated, the later it will run. For example the first middleware created by the proxy service is the middleware that will run after the request has been logged and proxied, thereby allowing it to access both the recorded request body and response body, and any context enrichment added by prior middleware. -```golang -service := ProxyService{} +https://github.com/Kava-Labs/kava-proxy-service/blob/847d7889bf5f37770d373d73cd4600a769ebd29c/service/service.go#L54-L110 -// create an http router for registering handlers for a given route -mux := http.NewServeMux() +## Middleware -// will run after the proxy middleware handler and is -// the final function called after all other middleware -// allowing it to access values added to the request context -// to do things like metric the response and cache the response -afterProxyFinalizer := createAfterProxyFinalizer(&service) +The middleware sequence of EVM requests to the proxy service: +![Middleware Sequence for Proxy Service](./images/proxy_service_middleware_sequence.jpg) -// create an http handler that will proxy any request to the specified URL -proxyMiddleware := createProxyRequestMiddleware(afterProxyFinalizer, config, serviceLogger) +### Decode Request Middleware -// create an http handler that will log the request to stdout -// this handler will run before the proxyMiddleware handler -requestLoggingMiddleware := createRequestLoggingMiddleware(proxyMiddleware, serviceLogger) +1. Captures start time of request for latency metrics calculations +1. Attempts to decode the request: + * As a single EVM request. If successful, forwards to Single Request Middleware Sequence with the request in the context. + * As a batch EVM request. If successful, forwards to Batch Processing Middleware with batch in context. + * On failure to decode, the request is sent down the Single Request Middleware Sequence, but with nothing in the context. -// register middleware chain as the default handler for any request to the proxy service -mux.HandleFunc("/", requestLoggingMiddleware) +### Single Request Middleware Sequence +If a single request is decoded (as opposed to a batch list), or the request fails to decode, it is forwarded down this middleware sequence. Additionally, each individual sub-request of a batch is routed through this sequence in order to leverage caching and metrics collection. -// create an http server for the caller to start on demand with a call to ProxyService.Run() -server := &http.Server{ - Addr: fmt.Sprintf(":%s", config.ProxyServicePort), - Handler: mux, -} -``` +This middleware sequence uses the decoded single request from the request context. -## Middleware +#### IsCached Middleware +The front part of the two-part caching middleware. Responsible for determining if an incoming request can be fielded from the cache. If it can, the cached response is put into the context. -### Request Logging Middleware +See [CACHING](./CACHING.md#iscachedmiddleware) for more details. -1. Logs the request body to stdout and stores a parsed version of the request body in the context key `X-KAVA-PROXY-DECODED-REQUEST-BODY` for use by other middleware. - -### Proxy Middleware +#### Proxy Middleware 1. Proxies the request to the configured backend origin server. +2. Times the roundtrip latency for the response from the backend origin server and stores the latency in the context key `X-KAVA-PROXY-ORIGIN-ROUNDTRIP-LATENCY-MILLISECONDS` for use by other middleware. -1. Times the roundtrip latency for the response from the backend origin server and stores the latency in the context key `X-KAVA-PROXY-ORIGIN-ROUNDTRIP-LATENCY-MILLISECONDS` for use by other middleware. +The Proxy middleware is responsible for writing the response to the requestor. Subsequent middlewares are non-blocking to the response. See [Proxy Routing](./PROXY_ROUTING.md) for details on configuration and how requests are routed. -### After Proxy Middleware +#### Caching Middleware +Handles determining if a response can be put in the cache if it isn't already. + +See [CACHING](./CACHING.md#cachingmiddleware) for more details. + +#### After Proxy Middleware 1. Parses the request body and latency from context key values and creates a request metric for the proxied request. + +### Batch Processing Middleware +1. Pulls decoded batch out of the request context +2. Separates into individual sub-requests +3. Routes each sub-request through the Single Request Middleware Sequence in order to leverage caching and metrics creation. +4. Combines all sub-request responses into a single response to the client. diff --git a/architecture/images/proxy_service_middleware_sequence.jpg b/architecture/images/proxy_service_middleware_sequence.jpg new file mode 100644 index 0000000..cc0ecf9 Binary files /dev/null and b/architecture/images/proxy_service_middleware_sequence.jpg differ