共通の機能を備えたさまざまな言語のライブラリがあります。 これらは、コンポジュレ、シナトラ、ブドウ、エクスプレス、コアなどです。
ルーティングにも同様のアプローチがあります。 それらは制限を課さず、URLを整理するための構造を提供しません。 このような状況にある開発者は、構造を気にせず、サポートが不十分なコードを受け取る傾向があります。
もう1つの一般的な機能は、一点性です。 つまり 特定のリクエストは特定のハンドラに対応します。 開発者は、テンプレート内の文字列でURLを登録する必要があります。 生成するURLを言語構成の形式で示す方法はありません。 これにより、デッドリンクがビューに残り、すべてのページに穴を開ける以外にそれらを見つける方法はありません。
Clojureエコシステムでコードサポートを改善する方法と、その方法を示します。
- URLを整理する
- 構造体ハンドラーコード
- 言語構造を使用してURLを生成します
上記のライブラリにはモジュール内でハンドラーを整理するためのツールがあり、関数内の文字列のURLを手動でラップし、これらの関数のみを使用できることを理解することが重要です。 しかし、原則として、彼らはそれについて考えるのが遅すぎます。
私はルビー開発者であり、他のエコシステム(clojure、js、erlang、go)では、レールのようなルーティング組織が不足しています。 RESTと「リソース」の概念が恋しいです。 コントローラーが恋しい。 admin_page_path(@page)
など、URLを生成するのに十分なヘルパーがありません。
レールに慣れていない場合は、ルーティングの説明「外部からのレールルーティング」へのリンクがあります。 HTTPまたはRESTのことを忘れた場合は、短くてユーモラスな記事「HTTPプロトコルで正しく動作することに関する15の些細な事実」またはより詳細な記事「このRESTが必要な理由、およびRESTfulアプリケーションの実装の複雑さ 」を読むことをお勧めします。
したがって、RESTを使用してURLを整理します。
残りの2つのポイントに対処するために、 darkleaf / routerライブラリの使用例を示します 。 なぜなら それはclojureエコシステムであり、そしてもちろん、それはリング互換のルーティングです。
(ns hello-world.core (:require [darkleaf.router :refer :all])) (def pages-controller {:middleware (fn [handler] (fn [req] req)) :member-middleware some-other-middleware :index (fn [req] some-ring-response) :show (fn [req] some-ring-response)}) (def routes (build-routes (resources :pages 'page-id pages-controller))) (def handler (build-handler routes)) (def request-for (build-request-for routes)) (handler {:uri "/pages", :request-method :get})
ここでは、レールと同様に、コントローラーが宣言されています。 この場合、indexとshowの2つのアクションがあります。
コントローラーは単なるマップであり、たとえば、関数を使用してわずかに異なるコントローラーを作成できます。
ルートは、リソースなどの関数によって生成されるルートのフラットベクトルです。
ハンドラーはリング互換の要求ハンドラーであり、request-forは、ルートの名前とスコープで要求を受信するために使用されます。 マクロを使用して生成されるのは、 core.match内で使用します。
コントローラには、次のキーのみを含めることができます。
- :ミドルウェア-ネストされたルートハンドラーを含むすべてのコントローラーアクションをラップします
- :メンバーミドルウェア-メンバーとしてマークされたメンバーアクションとネストされたルートハンドラーのみをラップします
- コレクションアクション::インデックス、:新規、:作成
- メンバーアクション::表示、:編集、:更新、:破棄
リソースの完全な例を次に示します。
(resources :pages 'page-id {:index identity :new identity :create identity :show identity :edit identity :update identity :destroy identity} :collection [(action :archived identity)] :member [(resources :comments 'comment-id {:index identity})])
最初の引数はリソースの名前を示し、urlのセグメントも設定します。 2番目のパラメーターは、リソースIDの名前を設定します。
前述したように、リソースには、コレクションとメンバーの2つのタイプのネストされたルートを含めることができます。
;; pages collection routes (request-for :archived [:pages] {}) ;; #=> {:uri "/pages/archived", :request-method :get} ;; pages member routes (request-for :index [:pages :comments] {:page-id "some-id"}) ;; #=> {:uri "/pages/some-id/comments", :request-method :get}
ルートの関数ジェネレーターに加えて、リソースにはルート、アクション、ワイルドカード、未検出、スコープ、ガード、リソースもあります。 それらについては詳しく説明しませんが、 テストでの使用の詳細な例を見つけるでしょう。
コントローラに新しいアクションを追加する方法はありません。 これは、RESTおよびネストされたリソースをプッシュする意図的な制限です。 それでも追加のアクションが必要で、添付リソースを使用したくない場合は、上記のroute:archivedに示すように、添付ルートを使用できます。 しかし、それはコントローラーの外部の独立した機能になります。
既にお気付きのように、URLのみを返すレールヘルパーとは異なり、 request-for
はリクエスト構造全体request-for
返します。 これは、ヘッダーまたはホストなどの他の要求パラメーターを使用してハンドラーを定義する場合に役立ちます。 将来のリリースでは、clojurescriptがサポートされる予定であり、同じリクエストを使用してバックエンドリクエストを作成できます。
なぜなら request-for
はリクエスト全体request-for
返し、受信したリクエストが目的のハンドラーに分類されるかどうかをチェックします。 これは、2つの類似したURLの処理方法が異なる場合、または制限が存在する場合に役立ちます。
(guard :locale #{"ru" "en"} (action :localized-page identity)) (not-found itentity)
(request-for :localized-page [:locale] {:locale "it"})
は、エラーをスローします。 /it/localized-page
ハンドラーは、 :localized-page [:locale]
ではなく、見つからないルートになり:localized-page [:locale]
。
ライブラリは2つの名前空間に分かれています。
darkleaf.routerおよびdarkleaf.router.low-level 。 特定のルーティング要件がある場合、または古いURLスキームをサポートする必要がある場合は、darkleaf.routerと同様に、darkleaf.router.low-levelの上に関数を記述できます。
完全な使用例は、 darkleaf.router-testおよびdarkleaf.router.low-level-testテストにあります。
このライブラリは、内部のcore.match
およびかなり興味深いマクロを使用します。 しかし、これは別の記事のトピックです。 これがどのように機能するかを知りたい場合は、コメントを書いてください。
更新日2017年10月2日、マクロおよびサードパーティライブラリなしでリリースされたバージョン0.2、clojurescript https://github.com/darkleaf/routerのサポートがあります