gpt4 book ai didi

clojure - 使用 Ring 和 Compojure 为不同的中间件提供应用程序和 API 路由

转载 作者:行者123 更新时间:2023-12-03 22:06:11 26 4
gpt4 key购买 nike

我有一个 ring+compojure 应用程序,我想根据路由是 Web 应用程序的一部分还是 api(基于 json)的一部分来应用不同的中间件。

我在堆栈溢出和其他论坛上找到了这个问题的一些答案,但这些答案似乎比我一直使用的解决方案更复杂。我想知道我的做法是否有缺点,以及我的解决方案中可能缺少什么。我正在做的一个非常简化的版本是

  (defroutes app-routes
(GET "/" [req] dump-req)
(route/not-found "Not Found"))

(defroutes api-routes
(GET "/api" [req] dump-req))

(def app
(routes (-> api-routes
(wrap-defaults api-defaults))
(-> app-routes
(wrap-defaults site-defaults))))

请注意,中间件比我在这里展示的要多。

我遇到的唯一“限制”是,由于 app-routes 有未找到的路由,它需要放在最后,否则会在找到 api 路由之前被触发。

这似乎比我发现的其他一些解决方案更简单、更灵活,这些解决方案似乎要么使用额外的条件中间件,例如 ring.middleware.conditional,要么在我看来是更复杂的路由定义,其中有一个额外的 defroutes 层并且需要使用任何“*”等定义defroutes。

我怀疑我在这里遗漏了一些微妙的东西,虽然我的方法似乎有效,但它会导致意外行为或在某些情况下导致结果等。

最佳答案

你是对的,排序很重要,但你缺少了一个微妙之处——你申请的中间件 api-routes对所有请求执行。

考虑这个代码:

(defn wrap-app-middleware
[handler]
(fn [req]
(println "App Middleware")
(handler req)))

(defn wrap-api-middleware
[handler]
(fn [req]
(println "API Middleware")
(handler req)))

(defroutes app-routes
(GET "/" _ "App")
(route/not-found "Not Found"))

(defroutes api-routes
(GET "/api" _ "API"))

(def app
(routes (-> api-routes
(wrap-api-middleware))
(-> app-routes
(wrap-app-middleware))))

和 repl session :
> (require '[ring.mock.request :as mock])
> (app (mock/request :get "/api"))
API Middleware
...
> (app (mock/request :get "/"))
API Middleware
App Middleware
...

Compojure 有一个很好的功能和帮助程序,可以在路由匹配后将中间件应用于路由 - wrap-routes
(def app
(routes (-> api-routes
(wrap-routes wrap-api-middleware))
(-> app-routes
(wrap-routes wrap-app-middleware))
(route/not-found "Not Found")))

> (app (mock/request :get "/api"))
API Middleware
...
> (app (mock/request :get "/"))
App Middleware
...

关于clojure - 使用 Ring 和 Compojure 为不同的中间件提供应用程序和 API 路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28016968/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com