<< RDRA リレーションシップ駆動分析から、いよいよ実装へ | main | ドメインモデル駆動開発の実践 >>

「仕事」を探す、URI 設計。 qeury 文字列方式は使わないぞ!

採用支援サイトの設計で、仕事を探す、検索機能の URI 設計を、やってみた。
基本は、「 query 文字列を使わない URI 設計 」のこころみ。

主に参考にした本は、

・Restful Web サービス
・Web を支える技術

実装技術としては、Spring 3 MVC の URI テンプレート機能を使う。 モデリングといいながら、@Controller の @RequestMapping の実装コードを、かなり意識している。

モデルとコードは、コインの表と裏のように結びついているし、距離も近いもの、という主義なので、だいたいこんな感じ。 Enterprise Architect で、 UML 風の絵を描きながら、頭の中は、結構、コードが飛び交っている。

基本の階層


求人案件の基本の分類整理軸は、悩ましい問題。
求人サイトでわりと多いのが、職種分類の階層。

http://example.com/job/{職種の大分類名}/{中分類名}/{小分類名}/{募集案件名}

(以下、http://example.com は省略)
( {パス要素} という記法は、Spring 3 MVC の URI テンプレートの {RequestVariable} の記法を使っている。)

例えば、

/job/クリエィティブ/web関連/webデザイナー/ソーシャルゲームのグラフィックデザイナ

という感じ。

下位のパス要素を記述しない場合は、

/job/ だけなら、職種の大分類の一覧
/job/クリティティブ/ なら、職種の中分類の一覧
...

という感じで、より、特定の仕事リソースに近づいていく。

画面でいえば、仕事リソースは、仕事の詳細表示画面で、そこで表示するパン屑リストが、この URI そのまま、という感じ。

リソースの一意識別


実際には、上記の「ソーシャルゲームのグラフィックデザイナ」の求人案件は、この URI では、一意に識別できない。

同じ職種名の案件が他にもある可能性がある。
かといって、職種名の下に、さらに階層があるかというと、ちょっと違う感じ。
職種名は、求人企業が任意に指定しているので、それが、分類の階層構造の一部というのは、たぶん、モデルとしてまちがい。

いちおう、今の設計案は、

/job/クリエィティブ/web関連/webデザイナー/ソーシャルゲームのグラフィックデザイナ.2996411

というように、最後の要素は、

{募集案件名}.{案件管理番号}

にしようと思っている。

RequestMapping のほうは、 /job/{zone}/{segment}/{category}/{jobtitle}.{id} と記述しておけば、それぞれのパス要素を、その変数名で簡単に取り出せる。

かなり乱暴だけど、

/job/*/*/*/*.{id} というマッチングで、 id だけ変数として、コントローラで処理することもできる。

ここらへの実装上の記法は、まだ、トライアル段階のところがあって、どう記述するか、手探り。

基本的には、いろいろな URI テンプレートののリストを、Spring が、 パターンマッチングをして、「特定できる順」に、一致させてくれるはず。

ただ、パターンを駆使して、解決をフレームワークにまかせる記法は、あいまいだったり、トリッキーで、障害の種だし、また、可読性も悪く、変更の副作用が怖い。

だから、できるだけ、明示的に書くことを重視しようと思っている。
( 変数として未使用でも、 * ではなく、{zone} のように、明示しようということ)

リソースの複数の分類体系


仕事は、データベース上では、実は、求人企業を親として、その下にぶら下がっている。
上記の、職種分類体系で、整理して持ているわけではない。

データベース上の構造をそのまま素直に URI にすると、

/job/{求人企業}/{求人案件名}.{求人番号}

になる。

ここで、第一階層の要素が、/job/ だと、さっきの、職種分類の /job/ と同じになってしまう。
複数のパス階層が並立する場合には、 /job/ だけでは、まずい。

で、考えたのが、

職種分類の階層は、 /job-category/
企業を親にする階層は、/company/

というように、使い分けることにした。

http://jobs.example.com/job-category/{zone}/{segment}

というように job は、サブドメインに持っていった。
仕事を探すサイト、が明確になったので、こっちのほうが、適切。

job-category とか、company とか、検索の切り口を、サブドメインにしてしまう、というのもちょっと考えた。

ただ、サイトとして、job-category.example.com だと、(政府の統計局とかの)、職種分類体系の検索サイトのような意味になりそう。 仕事を探す、というシンプルな目的とは、ちょっとずれる感じ。

company.example.com だと、さらにはっきりして、これだと、仕事探しではなく、企業情報リソース満載のサイト、という感じ。

というわけで、検索の視点の違いを、サブドメインで分けるのは、却下。
( Spring の URI テンプレートで、サブドメインの違いで処理を分けるというは、実装がややこしくなる、という実装面の問題もある)

ナビゲーションモデル


/company/{企業名}/{募集案件名}.{案件管理番号}

これは、データベースの構造のまま。
実際には、求職者向けのサービスとしては、こういう構造では提供していない。

/company/ で、ずらっと、求人企業が並ぶ。そこから、特定企業を選ぶと、
/company/Example株式会社/ というURIがリクエストされ、その企業の求人案件が並ぶ。

という画面は、普通なない。

/industory/{業種}/{企業名}/{募集案件名}.{案件管理番号}

というような感じで、「業種」から、企業を探す、というのがありそう。

あとは、

/area/{地域}/{都道府県}/{市区町村}

という勤務地を軸にした体系もありそう。

ナビゲーションの切り口は、職種分類、業種・企業、勤務地など、複数ある。
URI もそれぞれに応じた、体系にする。

ただし、最後の {募集案件名}.{案件管理番号} は、実体は一つにしておきたい。
同じ仕事(リソース)に、URI (一意識別情報) が複数あるのはおかしいでしょう、という、そもそも論。

実際には、一覧表示画面に、返す 正式(?)のURI は、

/company/{企業名}/{募集案件名}.{案件管理番号}

に統一しようと思っている。

/area/{地域}/{都道府県}/{市区町村}

のリクエストに対するレスポンス(リソース表現)は、 /company/{企業名}/{募集案件名}.{案件管理番号} のリストになる、ということ。

もうひとつの方法として、レスポンスは、

/area/{地域}/{都道府県}/{市区町村}/{募集案件名}.{案件管理番号}

という URI のリストにして、 この URI を受けとった、コントローラで、

/company/{企業名}/{募集案件名}.{案件管理番号}

に リダイレクトさせる、という方法も考えている。

ここらへんも、どちらが、より、開発しやすく、変更に強いか、という、現場での検討・評価が、まだなので、これから考えていこうと思っている。

後者のリダイレクト方式のほうが、意味的には、わかりやすいかなあ?

複合検索条件


今までの内容は、ツリー構造の分類体系を辿るパターン。

実際には、キーワード検索とか、複合条件の絞り込みとか、いろいろでてくる。
まだ、設計が固まっているわけではないけど、ワード検索だったら、

/keyword/{ワード}

とかにしようと思っている。

/keyword/ だけだと、検索キーワードが人気順にでてくる?

あるいは、

/keyword.10/ という URI で、上位の10件を表示、というような方向。

複合条件のほうは、セミコロンを使った、マトリクス指向の URI にしようと思っている。

首都圏の web デザイナーの仕事、月給は、月30万円以上、とかであれば、

/job/zone=首都圏;jobtype=webデザイナー;earnings=月30万円-

という感じ。 
最後の ハイフンは、範囲指定の常套(?)手段。 この場合は、下限だけ指定している。

spring 3 MVC のフレームワークがあって、spring エキスパートがいるので、このような URI の解析もさらっと実装してくれる(はず)。

そう思いこんで、私が、勝手に、こういう設計を先走っている。
(アンチパターンですね。危険ですね。設計は、関係者で、しょっちゅう、雑談的に意見交換することがたいせつ)

まあ、最悪、 ここらへんは、query 文字列方式に戻ればよい、という、リスク管理(?)をしながらやっているつもり。

いけそうかな?


現在の採用支援サイトの企画内容だと、こんな感じの URI 設計で、いけそうな気がしてきているところ。
今日一日で、がーっとやった仕事なので、ちょっと怪しいけど。
(でも、この日のために、前から URI 設計ネタはいろいろ仕込んできたつもり)

あとは、もっと具体的な仕事探しの機能と、実装技術で、この設計方針を確認しながら、成長させていこうと思っている。

今のところ、URI の要素には、積極的に日本語を使いたいと思っている。
「名前でリソースを表現する」には、やはり日本語が一番だから。

エンコーディングの関係で、問題がでるかあな? これも、早めに実験してつぶしておきたいリスク。

SEO 的には、こういう URI 設計、プラス効果があるのかな?
query 文字列方式は不利、という話は聞いたことがあるので、query 文字列なしのこっちの方式のほうが、よさげな気がするが、SEO は、門外漢なので、わかりません。 専門家に一度、相談しようと思っている。

あたかも静的ページがあるかのように、分類ツリーを網羅したサイトマップとかは、分類マスターから、簡単に自動生成できそうだな。
これは、素人考えでは、 SEO 的に意味がある気がする。
ロボットからみたら、大量の、完全に静的なページのツリー構造なので、query 方式よりも、検索の対象にうまくなってくれそうな気がする。
もちろん、これも、 SEO の専門家のアドバイス待ち。

リソース指向は面白い


もともと、自分は、データベース屋あがりなので、リソース指向は感覚的にあっている気がする。
CRUD と、 PUT/POST/GET/DELET とかは意味が違うけど、「定義済の少数の操作セット」という思想は、まったく同じ。

ただ、ちょっと前までは、 リソース指向の URI が良いな、と思っていても、実装のことを考えると、ちょっとなあ、と思っていた。

Spring 3 MVC で、REST スタイルがかなり実装しやすくなったのが、大きな転機。
URI をリソース指向でちゃんと設計すれば、それを、素直に、簡単に(?)、実装できそうな気がしている。

まあ、いつものことだけど、自分たちにとっては、初物で、実証済、経験済の技術ではないので、やってみると、いろいろあるとは思う。

でも、なんとなく、今回は、ちょっとしたターニングポイントの臭いがしている。
自分の勘が、どこかで、そういっている。

コメント
コメントする









この記事のトラックバックURL
トラックバック
calendar
  12345
6789101112
13141516171819
20212223242526
2728293031  
<< August 2017 >>
システム設計日記を検索
プロフィール
リンク
システム開発日記(実装編)
有限会社 システム設計
twitter @masuda220
selected entries
recent comment
  • 番号より名前。 ニーモニックコードより名前。 【パターン】
    師子乃 (03/10)
  • Smart UI が優れている?
    masuda220 (03/10)
  • Smart UI が優れている?
    kagehiens (03/09)
  • オブジェクト指向プログラミングの教え方?
    masuda220 (12/05)
  • オブジェクト指向プログラミングの教え方?
    ZACKY (12/04)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    masuda220 (08/14)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    kompiro (08/14)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    masuda220 (06/13)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    JHashimoto (06/13)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    masuda220 (02/28)
recent trackback
categories
archives
others
mobile
qrcode
powered
無料ブログ作成サービス JUGEM