Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

Pure map schemas are broken

Offen
#341 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Anfängerfreundlichkeit
28/100
Issue-Typ
Bug
Klarheit
Größtenteils klar
Aktivitätsstatus
Veraltet
Tech-Stack
clojure, openapi
Bereich
api, backend

Rechercherichtung

Beginne mit compojure.api.coercion.core/named-coercion und compojure.api.coercion.schema/json-coercion-matcher und verfolge anschließend die in der Issue gezeigte Konfiguration des Muuntaja-JSON-Decoders. Reproduziere eine Anfrage unter Verwendung des reinen Map-Schemas {s/Str s/Str}; als erledigt gilt dies, wenn String-Schlüssel während der Deserialisierung und Koerzierung Strings bleiben, ohne schema-keyed Maps zu beschädigen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

Not sure if thats by design, since Swagger doesn't seem to represent well pure maps, i.e. {s/Str s/Str}, but handling of those is broken atm.

What happens is that the default implementation forces Cheshire to keywordize all incoming maps while deserializing, so instead of {s/Str s/Str}, the request winds up as {s/Keyword s/Str} :(

The good (for my use case) news is that since Compojure API is almost infinitely extensible ;) I was able to:

  1. Override the JSON deserialization
  2. Plug a custom coercer

Something like this (only the important bits):

(ns blah.core
  (:require
           ;; just to show what cs and cc below resolve to
            [compojure.api.coercion.core :as cc]
            [compojure.api.coercion.schema :as cs])

;; coercion wiring

(defn keywordize-some
  "Keywordizes only the top-level map keys that are in the ks collection"
  [ks m]
  (reduce (fn [nm k]
            (if (keyword? k)
              (if-let [existing (get nm k)]
                nm
                (let [k-str (name k)]
                  (if-let [ex2 (get nm k-str)]
                    (-> nm
                        (assoc k ex2)
                        (dissoc k-str))
                    nm)))
              nm))
          m
          ks))

(defn json-coercer [schema x]
  "Coerces a map value with a map schema - otherwise falls back to the original coercer"
  (if (map? x)
    (keywordize-some (keys schema) x)
    (if-let [fallback (cs/json-coercion-matcher schema)]
      (fallback x)
      x)))

(defn jcm [schema]
  (if (map? schema)
    (partial json-coercer schema)
    (cs/json-coercion-matcher schema)))

(defmethod cc/named-coercion :json [_] (cs/create-coercion {:body     {:default (constantly nil)
                                                                       :formats {"application/json"    jcm
                                                                                 "application/msgpack" jcm
                                                                                 "application/x-yaml"  jcm}}
                                                            :string   {:default cs/string-coercion-matcher}
                                                            :response {:default (constantly nil)}}))

(api
    ....
     ;; wire a non-keywordizing JSON deserializer
     ;; the actual keywordization will be done in a custom coercer
     :formats    (-> (:formats compojure.api.api/api-defaults)
                     (assoc-in [:formats muuntaja.format.json/json-type] {:decoder [muuntaja.format.json/make-json-decoder {}]
                                                                          :encoder [muuntaja.format.json/make-json-encoder]}))

     ;; our custom coercer registered via defmethod above
     :coercion   :json
    ...
     }
Vorherrschende Sprache
Clojure
Sterne
1.1k
Forks
144
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus metosin/compojure-api

Alle Issues in metosin/compojure-api

Ähnliche Issues

Weitere Issues zu Clojure

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.