-
-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplified syntax / higher-level abstractions for making HTTP Requests with schema decoding and retries #3735
Comments
The issue with the old API is lack of composability having a mix of default instances and context-accessed apis, the current version is standard in effect, the default way to expose functionality is via services and accessing services is first-class supported in effect |
that said my feeling is that the HttpClient apis need complete reset, we are trying way too hard to abstract and the current API is not usable by the average developer (including myself), it's not a doc problem it's an API problem. |
Some changes have been made to bring the same service methods ( This makes it easier to use a client without using the service approach. Here are some usage patterns that are available now: import { FetchHttpClient, HttpClient, HttpClientResponse } from "@effect/platform"
import { BrowserHttpClient } from "@effect/platform-browser"
import { NodeHttpClient } from "@effect/platform-node"
import { Schema } from "@effect/schema"
import { Effect, ManagedRuntime, Schedule } from "effect"
const todoListSchema = Schema.Array(Schema.Unknown)
// you could provide a client directly:
async function listTodos(url: string, headers: Headers, searchParams: URLSearchParams) {
return Effect.runPromise(
HttpClient.get(`${url}?${searchParams.toString()}`, { headers }).pipe(
Effect.flatMap(HttpClientResponse.filterStatusOk),
Effect.flatMap(HttpClientResponse.schemaBodyJson(todoListSchema)),
Effect.scoped,
Effect.retry({
times: 3,
schedule: Schedule.exponential(1000)
}),
Effect.provide(FetchHttpClient.layer)
)
)
}
// or use a ManagedRuntime:
const runtime = ManagedRuntime.make(
FetchHttpClient.layer
// or one of these:
//
// NodeHttpClient.layer,
// NodeHttpClient.layerUndici,
// BrowserHttpClient.layerXMLHttpRequest
)
async function listTodos(url: string, headers: Headers, searchParams: URLSearchParams) {
return runtime.runPromise(
HttpClient.get(`${url}?${searchParams.toString()}`, { headers }).pipe(
Effect.flatMap(HttpClientResponse.filterStatusOk),
Effect.flatMap(HttpClientResponse.schemaBodyJson(todoListSchema)),
Effect.scoped,
Effect.retry({
times: 3,
schedule: Schedule.exponential(1000)
})
)
)
}
// or the recommended service approach:
export class Todos extends Effect.Service<Todos>()("Todos", {
effect: Effect.gen(function*() {
const client = HttpClient.filterStatusOk(yield* HttpClient.HttpClient)
const list = (url: string, headers: Headers, searchParams: URLSearchParams) =>
client.get(url, {
headers,
urlParams: searchParams
}).pipe(
Effect.flatMap(HttpClientResponse.schemaBodyJson(todoListSchema)),
Effect.scoped,
Effect.retry({
times: 3,
schedule: Schedule.exponential(1000)
})
)
return { list } as const
}),
dependencies: [NodeHttpClient.layerUndici]
}) {} |
What is the problem this feature would solve?
In
@effect/platform
version 0.63, HTTP requests could be retried and decoded with this syntax:The above code strikes me as something that an average TypeScript application developer could understand and maintain. It is also consumable by code that doesn't have to know about Effect.
Now, in version 0.66, we would have to write generator functions and classes to achieve the same thing:
https://github.com/Effect-TS/effect/blob/main/packages/platform/README.md#integration-with-schema
and from the effect.website home page, retries:
The new documented syntax is not something I would feel comfortable advocating that a real team of average TypeScript application developers adopt, since it is significantly more complex at the application logic layer. The new documented syntax is also more complex than achieving the same thing without any dependencies, as demonstrated on the website's home page:
I was super excited about the Effect project's way of solving the request / decode / retry class of problems, but I'm now feeling very nervous about introducing it into my project's code, and am honestly considering abandoning it as a dependency over performing the upgrade and refactor indicated by the example code above due to the new bits of complexity team members would have to think about and maintain:
What is the feature you are proposing to solve the problem?
I'd love to have higher level abstractions over HTTP Client modules, similar to what was in version
@effect/platform
0.63 (but not necessarily identical). I am happy to refactor in order to upgrade, and do not expect stability of these v0 APIs, but the increased complexity from application developers' point of view with the recent changes to:...has been very hard to digest.
But thank you so much for making this open source library! I understand that it's hard to make APIs that please everyone, and really appreciate all the work that has gone into every version, even the one I'm hoping will change 💕
What alternatives have you considered?
No response
The text was updated successfully, but these errors were encountered: