3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DM機能のURL設計について

Posted at

こんにちは!Yuyaです。
現在、Xのクローンアプリを開発しています。
DM機能の実装でレビューをいただき、RESTfulなURL設計についてご指摘をいただいたのでアウトプットしていきます。

レビュー前のURLについて

以下がレビュー前のコードです。

config/urls.py
from django.urls import include, path

urlpatterns = [
    ...
    path('message/', include('apps.chats.urls')),
    ...
]
chats/urls.py
from django.urls import path
from .views import RoomUserListView, MessageView, CreateMessageView

app_name = 'chats'

urlpatterns = [
    path('', RoomUserListView.as_view(), name="message_list"),
    path('<int:user1_id>-<int:user2_id>/', MessageView.as_view(), name="message"),
    path('<int:user1_id>-<int:user2_id>/create/', CreateMessageView.as_view(), name="message_create"),
]

なぜこのようなURL設計にしたのか

  • XのDM機能が /messages/<user1_id> - <user2_id>となっていたから
  • RESTfulなURL設計を考えていなかったから
  • URLで送信者-受信者とした方が直感的にわかりやすいと考えたから

レビュー内容

自分のuser_idsessionから撮れば良いので、相手のuser_idのみパスパラメータで取得するのが良い。パスに関しては、users/:user_id/messagesのようにするのがよいですね。

めちゃくちゃ引っかかった部分がありました。
それはパスに関しての文章です。

私の考えとしてはレビューをいただいてからも以下の考えは変わりませんでした。

  • /message:メッセージ一覧
  • /message/<user1_id> - <user2_id>:任意のユーザーとのメッセージ一覧

messageから始まっているのに、なぜusersが次に来るのかわからず
流石にこれはレビュワーの方がタイポ?考えが間違っているのではないかと思ったので、同じ課題を取り組んでいる方に相談をしました。

HC生と技術的な相談をして

結論、私のURL設計がRESTfulではないということが明らかになりました。
具体的には5つの問題が発生します。

曖昧性

  • user1が自分でuser2が相手なのか不明
  • URLだけ見て誰の視点かわからない
  • 同じ会話に対して複数のURLが存在する可能性

権限チェックの複雑化

  • user1, user2どちらがログインユーザーなのかチェック
  • 相手ユーザーのIDを特定

非直感的なURL構造

/message/123-456/create/  # 何を作成するのか不明確

セキュリティ面での問題

# URLから他人の会話を推測可能
/message/100-101/  # ユーザー100と101の会話
/message/100-102/  # ユーザー100と102の会話
/message/101-102/  # ユーザー101と102の会話(推測可能)

動詞を使用している

# messageは動詞
path('message/', include('apps.chats.urls')),

# createは動詞
path('<int:user1_id>-<int:user2_id>/create/', CreateMessageView.as_view(), name="message_create"),

単数形vs複数形の非統一

  • RESTfulでは複数形が標準
  • 一覧取得なのか個別取得なのか区別できない

改善後

レビューワーの方からのご指摘を受けて、RESTfulなURLを意識したURLは以下のようになりました!

config/urls.py
from django.urls import include, path

urlpatterns = [
    ...
    path('messages/', include('apps.chats.urls')), #messagesと複数形に変更
    ...
]
chats/urls.py
from django.urls import path
from .views import RoomUserListView, MessageView

app_name = 'chats'

urlpatterns = [
    path('', RoomUserListView.as_view(), name="message_list"),
    
    # # GET, POST
    path('users/<int:receiver_id>/messages', MessageView.as_view(), name="message"),
]

RESTful URL設計時のチェックポイント

  • 名詞を使用している(動詞を避けている)
  • 複数形を使用している
  • 階層構造でリソースの関係を表現している
  • HTTPメソッドでアクションを表現している
  • 一貫性のある命名規則を使用している
  • URLから技術的詳細を隠している
  • 略語を避けて明確な名前を使用している
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?