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
Seems incompatible with ring-cors
#143
Comments
Hi, and thanks for the repro. Reitit takes a The repro routing tree doesn't have an 0 - document the route-first approach properly
1 - automatically create the
|
I think it makes sense to be able to support option 0, whether or not you choose to solve this problem via option 0. Which is to say, there exists an indeterminate number of libs that work in a way that is incompatible with reitit's route-first philosophy, and I think it would be useful to support that in general In order to make 0 work, however, something must be done about the use of metadata to attach the routes to the ring-handler. A helper function to preserve the metadata like (defn outer-middleware [ring-handler middleware] ...) might be all that is needed. This would effectively support exemptions from the route-first rule. edit: a word, formatting |
For 0, we could add a optional 3rd argument to the (def app
(ring/ring-handler
(ring/router
["/ping" (constantly {:status 200, :body "pong"})])
(ring/create-default-handler)
{:middleware [wrap-log wrap-cors]})) The implementation would actually push the middleware on top of all endpoints middleware stack, so they are part of the endpoint documentation too. The |
I do like your idea more, with the optional map containing |
I think that the solution should have:
|
Thanks for the comments. @stijnopheide Related to 2, both middleware & interceptors can inspect the route data both at runtime (like yada) and also at creation time. Still, neither way can be used to modify the resource the endpoint data, e.g. add For now, to solve this inside a router - the (note to self: need to think how to make the router compiler more composable to allow multiple standalone compilers to run) In all cases, all the request-time processing in reitit is stuffed into middleware & interceptors, which need to be parametrized to do their work. Options are: I) via arguments to middleware/interceptors With I, we could use the With some googling, at least these options seem to exist: {:access-control
{:allow-origin "http://foo.example"
:allow-methods #{:get :post :put}
:allow-credentials true
:allow-headers #{"X-PINGOTHER" "Content-Type"}
:expose-headers #{"X-My-Custom-Header" "X-Another-Custom-Header"}
:max-age 86400}} |
Default |
Related to adding top-level middleware to router (retaining meta-data), see #146. |
Did a PR (#148) to generate the undocumented Deployed in Clojars as |
Yes it does! looks good :D |
what do you think @stijnopheide? The cors (middleware/interceptor) is an addon on top of this. I think the default could return the methods too:
Goal in not to try to be 100% http compliant, but I guess there is no reason not to push that info to the clients... |
@ikitommi, yes I think that'll work for us! |
Thanks for the comments. Added the => |
I'm not proud to admit this, but I've been wrestling with CORS issues for the past two days. I switched from For someone like me who is less familiar with the data-driven middleware approach, can anyone provide an example of how to use
...it's unclear to me how I can apply these kwargs to I'm currently failing with the following setup: (-> (ring/ring-handler
(ring/router
[my-routes]
{:data {:coercion reitit.coercion.spec/coercion
:muuntaja m/instance
:middleware [wrap-params
muuntaja/format-middleware
coercion/coerce-exceptions-middleware
coercion/coerce-request-middleware
coercion/coerce-response-middleware]}})
(ring/create-default-handler)
{:middleware [[wrap-cors :access-control-allow-origin #"http://localhost:3000"]]})
(jetty/run-jetty {:port 9001 :join? false}))
In general I feel like CORS is a pretty simple concept. In practice, I feel like I'm tripping over it. |
@wpcarro the steps that got it working for me were
As a function:
As a vector:
|
Here's what ended up working for me: (def router-config
{:data {:coercion coercion-spec/coercion
:muuntaja m/instance
:middleware [swagger/swagger-feature
muuntaja/format-middleware
exception/exception-middleware
coercion/coerce-request-middleware
coercion/coerce-response-middleware
]}})
(defn routes
[env]
(ring/ring-handler
(ring/router
["/v1" {:middleware [#(wrap-cors %
:access-control-allow-origin [#".*"]
:access-control-allow-credentials "true"
:access-control-allow-methods [:get :post :put :delete])]}
(app/routes env)]
router-config)))
(defn app
[env]
(router/routes env)) |
Minimal repro case. README contains repro instructions.
https://github.com/levitanong/repro-reitit-cors
Ring-cors automatically accepts
OPTIONS
and specially treats preflight requests. Currently, the only way i've found to make it work is by wrapping the ring-handler itself, circumventing the idiomatic:middleware
keys. The trade off is, the metadata is lost, and to preserve some functionality, we must extract that metadata andwith-meta
the wrapped handler with the extracted metadata.The text was updated successfully, but these errors were encountered: