OpenApi: optional query and header parameters are documented as nullable
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 57/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- typescript
- Ambito
- api
Direzione di ricerca
Start in OpenApi.ts at processParameters, the entry point named in the issue, and trace how optional query and header parameter schemas pass through the representation pipeline. Compare those parameter schemas with the body handling described in the issue, then inspect or add focused tests for OpenApi.fromApi query and header output. Done means optional parameters omit JSON null while preserving the documented string forms, with body behavior unchanged.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
What version of Effect is running?
4.0.5. Also seen on 4.0.0. OpenApi.ts on main is the same as in 4.0.5.
What steps can reproduce the bug?
OpenApi.fromApi documents a query parameter declared with Schema.optional as anyOf: [T, null]. A query string has no way to send null, and the server's query decoder doesn't accept one.
import { Schema } from "effect"
import { HttpApi, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/http-api"
const Query = Schema.Struct({
limit: Schema.optional(Schema.FiniteFromString),
cursor: Schema.optional(Schema.NullOr(Schema.String))
})
const Api = HttpApi.make("api").add(
HttpApiGroup.make("items").add(
HttpApiEndpoint.get("list", "/items", { query: Query, success: Schema.String })
)
)
console.log(JSON.stringify(OpenApi.fromApi(Api).paths["/items"].get.parameters, null, 2))
// What the server does with the `null` the document allows
const decodeQuery = Schema.decodeUnknownExit(Schema.toCodecStringTree(Query))
console.log(decodeQuery({ limit: "null" })._tag) // "Failure"
What is the expected behavior?
limit documented as { "type": "string" } with required: false. required: false already says the parameter can be left out, so the undefined that Schema.optional adds has nothing left to describe.
cursor documented with only the string form of its NullOr, anyOf: [{ "type": "string", "enum": ["null"] }, { "type": "string" }], and no JSON null around it.
What do you see instead?
[
{
"name": "limit",
"in": "query",
"schema": { "anyOf": [{ "type": "string" }, { "type": "null" }] },
"required": false
},
{
"name": "cursor",
"in": "query",
"schema": {
"anyOf": [
{ "anyOf": [{ "type": "string", "enum": ["null"] }, { "type": "string" }] },
{ "type": "null" }
]
},
"required": false
}
]
cursor shows the mismatch most clearly. Its NullOr gets the query codec's representation, the string "null". The undefined from Schema.optional gets the JSON codec's, where Undefined encodes as null. One parameter ends up described by two codecs.
Additional information
- Headers have the same problem:
headers: Schema.Struct({ "x-trace": Schema.optional(Schema.String) })comes out asanyOf: [{ "type": "string" }, { "type": "null" }]. - Bodies are fine. A JSON body does decode
nulltoundefined, soT | nullis the right description there. - Effect's own
HttpApiClientis unaffected, since it dropsundefinedbefore building the URL. Clients generated from the document are the ones that break. We generate ours with orval, which typeslimitasstring | nulland sends?limit=nullwhen givennull. The service then rejects the request, or, for a plainSchema.String, reads"null"as a real value. - Switching to
Schema.optionalKeyfixes the document. It also makes{ limit: undefined }fail to encode, so every caller that builds a query from a possibly-undefined value has to leave the key out by hand, which is whatSchema.optionalexists to avoid. - A possible workaround until it's fixed: an
OpenApi.Transformthat drops thenullmember from every parameter whererequiredisfalse. - My guess at the cause, from reading the source:
processParametersqueues parameter schemas as"properties"ops, and those go through the same representation pipeline as bodies, so an optional property'sundefinedgets the JSON rule.
- Lingua principale
- TypeScript
- Stelle
- 16.7k
- Fork
- 808
- Merge medio
- 10h 12m
- PR unite (30g)
- 813
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Effect-TS/effect
-
BrowserWorkerRunner: port finalizer throws when the worker global has no close() (Bun)Forse già presa @santiago-ramos-02 l’ha presa 20 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
Effect-TS/effect#8635 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Support {self: this} for fnUntracedForse di nuovo libera @ArjunCodess l’ha presa 31 giorni fa e non c’è nessuna pull request aperta. Apertaenhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
Effect-TS/effect#8101 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 5/5 Più di una settimana Idoneità per principianti 32/100
Effect-TS/effect#9610 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Schema.isStringFinite (and Number string matching) takes quadratic time on long digit runsForse già presa @magoz l’ha presa oggi. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 66/100
I maintainer di solito rispondono entro 1 giorno
-
Schema.isBase64 / isBase64Url throw RangeError on multi-megabyte stringsForse già presa @magoz l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 20/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di Effect-TS/effect
Issue simili
-
area: repo priority: P2 type: bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
appandflow/stim#4107 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficoltà 1/5 1-3 ore Idoneità per principianti 60/100
lingdojo/kana-dojo#32859 · 1 commento · 5 reazioni ·
I maintainer di solito rispondono entro 1 giorno
-
code-quality refactoring
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
github/gh-aw-firewall#10364 ·
I maintainer di solito rispondono entro 1 giorno
-
Merge the duplicate kaffir_corn record into sorghumForse già presa @Crypto-Shroom l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
Crypto-Shroom/Bird-Feed-Calculator#322 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
drizzle-team/drizzle-orm#6552 ·
I maintainer di solito rispondono entro 2 giorni