SvelteKit app where the API is implemented using @effect/rpc. Includes OTEL tracing.
Use routes/api/[...paths]
to create multiple API endpoints simultaneously, the handler is derived from an Effect HTTP App
.
In load functions, SvelteKit provides a custom event.fetch
. Among other things, during SSR it skips network calls to internal APIs and avoids refetching data on the client.
Use the HttpClient.client.Fetch
Tag
to provide event.fetch
to Effect.
@effect/rpc batches multiple RPC requests in a single HTTP request. The body of the HTTP request is the array of RPC request bodies, which are JSON objects. For tracing, each RPC request is assigned separate trace ID and span ID (the HTTP request is also assigned a separate trace ID and span ID).
This is incompatible with SvelteKit event.fetch
caching during SSR. On the server, event.fetch
caches responses in the HTML; during hydration, event.fetch
retrieves the responses from the HTML cache.
The problem is that the cache key is the hash of the request header and body. The HTTP request body includes each RPC's trace ID and span ID, which differ between SSR and hydration, resulting in cache misses.
To solve this problem we introduce the custom X-SvelteKit-Hash
header and patch SvelteKit to use its value as cache key. The value of the header is the hash of the request header and body, omitting trace IDs and span IDs.