Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
Tommi Reiman edited this pageFeb 2, 2017 ·12 revisions

Compojure-api usesCompojure for routing.

The big difference is, that all compojure-api route functions & macros returncompojure.api.routes/Route-records which can both act as normal ring handlers (e.g. can be called with request to produce an response) and they satisfy thecompojure.api.routes/Routing protocol for collecting the route information.

(definc-route  (GET"/inc" []:query-params [x:- s/Int]:return {:result s/Int}    (ok {:result (inc x)})))inc-route; #Route{:path "/inc";        :method :get;        :info {:parameters {:query {Keyword Any, :x Int}};               :responses {200 {:schema {:result Int}, :description ""}}}}(inc-route {:request-method:get,:uri"/inc":query-params {}}); CompilerException clojure.lang.ExceptionInfo: Request validation failed: {:x missing-required-key}(inc-route {:request-method:get,:uri"/inc":query-params {:x1}}); {:status 200, :headers {}, :body {:result 2}, :compojure.api.meta/serializable? true}

At api creation time, the route-tree is walked and the reverse-route tree is generated - to be used both for swagger-docs & for bi-directional routing. To resolve the route-tree manually, you can callget-routes.

(compojure.api.routes/get-routes  (context"/api" []    inc-route    (POST"/mortem" []:summary"oh, noes"      (ok {:rest"in piece"})))); [["/api/inc" :get {:parameters {:query {Keyword Any, :x Int}}, :responses {200 {:schema {:result Int}, :description ""}}}];  ["/api/mortem" :post {:summary "oh, well"}]]

Bi-directional routing

Routes can have a (preferably qualified) keyword:name. When anapi is created, a reverse route tree is created from it's subroutes and the routing table is injected into the request. One can get a full string path to a route by calingcompojure.api.routes/path-for* with the request, route name and optionally path-parameters as a map. There is also a helper macrocompojure.api.routes/path-for which reads the request from lexical scope bindings. It is only available in the http endpoint macros (GET,POST etc.). Path parameters are written into Strings using standard JSON decoding.

(require '[compojure.api.routes:as routes])(defapp  (api;; a named route    (GET"/pong/:id" []:path-params [id:- s/Int]:name::pong      (ok {:id id}));; reverse routing via a macro    (GET"/ping1" []      (temporary-redirect (routes/path-for::pong {:id1})));; reverse routing via function    (GET"/ping2" request      (temporary-redirect (routes/path-for*::pong request {:id2})))))(app {:request-method:get,:uri"/ping1"}); {:status 307, :headers {"Location" "/pong/1"}, :body ""}(app {:request-method:get,:uri"/ping2"}); {:status 307, :headers {"Location" "/pong/2"}, :body ""}

Undocumented routes

If the api routes contain routes, which do not satisfy theRouting protocol (e.g. normal ring/compojure functions), an callback-function[:api :invalid-routes-fn] is called. By default, an warning is logged. At runtime, everything works as expected.

Mixing compojure-api with vanilla ring handlers

By default, aWARN is logged.

(api  (GET"/ping" []    (ok {:message"I satisfy the Routing protocol!"}))  (compojure.core/GET"/pong" []    (ok {:message"I dont."}))); WARN Not all child routes satisfy compojure.api.routing/Routing. {:path nil, :method nil}, invalid child routes: [#function[compojure.core/if-method/fn--19598]]

Marking routesundocumented will stop the route collector to entering those routes (still works at runtime thou).

(api  (GET"/ping" []    (ok {:message"I satisfy the Routing protocol!"}))  (undocumented    (compojure.core/GET"/pong" []      (ok {:message"I dont."}))))

You can also mark compojure-api routes asundocumented - here, the whole api is undocumented

(api  (undocumented    (GET"/ping" []      (ok {:message"I satisfy the Routing protocol!"}))    (compojure.core/GET"/pong" []      (ok {:message"I dont."}))))

One can also change how the api handles non-compojure-api routes. Here, we break at compile-time:

(api  {:api {:invalid-routes-fn compojure.api.routes/fail-on-invalid-child-routes}}  (GET"/ping" []    (ok {:message"I satisfy the Routing protocol!"}))  (compojure.core/GET"/pong" []    (ok {:message"I dont."}))); CompilerException clojure.lang.ExceptionInfo: Not all child routes satisfy compojure.api.routing/Routing. {:path nil, :method nil, :invalid [#function[compojure.core/if-method/fn--19598]]}

... or just ignore the bad routes

(api  {:api {:invalid-routes-fnnil}}  (GET"/ping" []    (ok {:message"I satisfy the Routing protocol!"}))  (compojure.core/GET"/pong" []    (ok {:message"I dont."})))

Not found (at runtime)?

To set up a "didn't match anything" handler within anapi, just do like you would do with ring/compojure.

(api  inc-route  (undocumented    (compojure.route/not-found (ok {:not"found"}))))
Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp