sukovanej / effect-http

Declarative HTTP API library for effect-ts
https://sukovanej.github.io/effect-http
MIT License
247 stars 20 forks source link

setRequestQuery does not accepts accepts number enums #622

Closed wewelll closed 1 month ago

wewelll commented 1 month ago

On the latest version of effect-http (0.73.0), request query is forced to be a string. It's a breaking change for enums wrapping numbers. What is the best way to make this code work again ?

enum MyEnum {
  one = 1,
  two = 2,
  three = 3,
}

const endpoint = ApiEndpoint.get('getData', '/data').pipe(
  Api.setRequestQuery(
    S.Struct({
      // TS error => "Type 'MyEnum.one' is not assignable to type 'string | readonly string[] | undefined'."
      numberEnum: S.Enums(MyEnum),
    })
  )
);
sukovanej commented 1 month ago

Are you sure this ever worked? Query parameters are always strings so validating number enums should always fail.

This works for me - Schema.compose(QuerySchema.Number, Schema.Enums(MyEnum))

import { NodeRuntime } from "@effect/platform-node"
import { Schema } from "@effect/schema"
import { Effect, Logger } from "effect"
import { Api, ApiEndpoint, QuerySchema, RouterBuilder } from "effect-http"
import { NodeServer } from "../src/index.js"

enum MyEnum {
  one = 1,
  two = 2,
  three = 3
}

const endpoint = ApiEndpoint.get("getData", "/data").pipe(
  Api.setRequestQuery(
    Schema.Struct({
      numberEnum: Schema.compose(QuerySchema.Number, Schema.Enums(MyEnum))
    })
  )
)

const api = Api.make().pipe(
  Api.addEndpoint(endpoint)
)

const app = RouterBuilder.make(api).pipe(
  RouterBuilder.handle("getData", ({ query }) => Effect.log(`Number ${query.numberEnum}`)),
  RouterBuilder.build
)

app.pipe(
  NodeServer.listen({ port: 3000 }),
  Effect.provide(Logger.pretty),
  NodeRuntime.runMain
)
wewelll commented 1 month ago

Yes I'm almost sure it was working, we've never seen an error on these endpoints. Thanks for the help, I should be able to fix it with S.compose and QuerySchema.Number