Skip to content
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

Request contains nil :body and :query-string #329

Open
conan opened this issue May 31, 2018 · 5 comments
Open

Request contains nil :body and :query-string #329

conan opened this issue May 31, 2018 · 5 comments
Labels

Comments

@conan
Copy link

conan commented May 31, 2018

I've tried using both jetty and httpkit, in both cases my request maps contain nil values for the optional keys :body and :query-string; this is not compliant with the :ring/request spec. Is it possible to remove the keys from the request map instead of setting them to nil in order to remain spec compliant?

Call to #'hanabi.web/initialise did not conform to spec:
web.clj:181

-- Spec failed --------------------

Function arguments

  ({:reitit.core/match ...,
    :reitit.core/router ...,
    :remote-addr ...,
    :params ...,
    :headers ...,
    :async-channel ...,
    :server-port ...,
    :content-length ...,
    :form-params ...,
    :websocket? ...,
    :web/session ...,
    :query-params ...,
    :content-type ...,
    :character-encoding ...,
    :uri ...,
    :server-name ...,
    :query-string ...,
    :path-params ...,
    :body nil,
          ^^^
    :scheme ...,
    :request-method ...})

should satisfy

  #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x765709fc "clojure.spec.alpha$regex_spec_impl$reify__2436@765709fc"]

-- Relevant specs -------

:ring.request/body:
  :clojure.spec.alpha/unknown
:ring/request:
  (clojure.spec.alpha/keys
   :req-un
   [:ring.request/server-port
    :ring.request/server-name
    :ring.request/remote-addr
    :ring.request/uri
    :ring.request/scheme
    :ring.request/protocol
    :ring.request/headers
    :ring.request/request-method]
   :opt-un
   [:ring.request/query-string :ring.request/body])
:web.ring/request:
  (clojure.spec.alpha/merge
   :ring/request
   (clojure.spec.alpha/keys
    :req
    [:web/session]
    :req-un
    [:web.ring.request/edn-params]))

-- Spec failed --------------------

Function arguments

  ({:reitit.core/match ...,
    :reitit.core/router ...,
    :remote-addr ...,
    :params ...,
    :headers ...,
    :async-channel ...,
    :server-port ...,
    :content-length ...,
    :form-params ...,
    :websocket? ...,
    :web/session ...,
    :query-params ...,
    :content-type ...,
    :character-encoding ...,
    :uri ...,
    :server-name ...,
    :query-string nil,
                  ^^^
    :path-params ...,
    :body ...,
    :scheme ...,
    :request-method ...})

should satisfy

  #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x765709fc "clojure.spec.alpha$regex_spec_impl$reify__2436@765709fc"]

-- Relevant specs -------

:ring.request/query-string:
  :clojure.spec.alpha/unknown
:ring/request:
  (clojure.spec.alpha/keys
   :req-un
   [:ring.request/server-port
    :ring.request/server-name
    :ring.request/remote-addr
    :ring.request/uri
    :ring.request/scheme
    :ring.request/protocol
    :ring.request/headers
    :ring.request/request-method]
   :opt-un
   [:ring.request/query-string :ring.request/body])
:web.ring/request:
  (clojure.spec.alpha/merge
   :ring/request
   (clojure.spec.alpha/keys
    :req
    [:web/session]
    :req-un
    [:web.ring.request/edn-params]))

-------------------------
Detected 2 errors
@ikitommi
Copy link
Contributor

I think at least :query-string should be s/nillable. Both Immutant and Aleph use custom Map implementations with predefined keys but the implementations read the values directly from underlaying implementations, which can return nil.

@weavejester
Copy link
Member

If the Jetty adapter is doing the wrong thing it should be fixed.

I'm not sure whether the best thing to do is to make the keys nillable. I currently lean toward not, as that gives more relevance to contains?, e.g. (contains? request :query-string). I'm also reluctant to treat nil and a missing key as being the same, if Clojure spec itself treats them differently.

If Immutant and Aleph use a custom map implementation, I don't see any reason why they also can't dictate a key as being missing.

@ikitommi
Copy link
Contributor

Both Aleph & Immutant use zero-copy requests where the shape of the request needs to be defined forehand and the values are lazily fetched on-demand from the underlaying impementation (Netty or Undertow). This is a big win in performance, but can't strip away keys (in a performant way).

@weavejester
Copy link
Member

If get is calculated on the fly, then contains? can be as well. The only performance hit would be in keys, but arguably it would return better information as a result.

In terms of pros and cons, here's how I see it:

Pros for adding nils

  • Currently incorrect adapters wouldn't have to fix their implementations
  • Adapters would be a little easier to write
  • Request maps could be records

Cons

  • We'd have to update the spec
  • There would be two ways of denoting optional keys instead of one
  • Less idiomatic?
  • contains? and keys become much less useful
  • As we make more keys optional (e.g. :headers), more things would become nillable as well

I'm not quite sure what the best option is. My inclination is that allowing nils would make life a little easier for adapter writers, but might make the job of end developers a little more complex. My current inclination is to side with the latter, but I'm open to convincing.

@conan
Copy link
Author

conan commented Jun 1, 2018

I don't have a strong argument either way. My feeling from an idiomatic perspective is that nil should not be allowed, but my feeling from a pragmatic perspective is that this issue can be fixed more easily if they are. Though my inner aesthete complains, I think I'd also side with the latter because I haven't been able to find any complaints about the current behaviour that allows nils, and I'd rather the issue was fixed than not. Not very helpful, sorry.

@weavejester weavejester added the bug label Nov 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants