2

很多框架都使用 URL 约定/controller/action/{id},这很好,但是如果您需要除此之外的任何配置,则由您自己编写路由。

您将如何处理/users/{id}/friends后端的 URL?(列出用户的所有朋友)

我认为在控制器中,这样的事情是合适的:

class User {
    function index() {
        echo 'user index';
    }
}

class Friend extends User {
    function index($user_id) {
        echo 'friend index';
    }    
}

然后你会得到以下地图:

/users              -> User::index()
/users/{id}         -> User::view($id)
/users/{id}/friends -> Friend::index($user_id)

我想把 Friend 类放在 User 类中,但显然你不能在 PHP 中这样做,所以这是我能想到的最好的方法。想法?

什么 URL 将用于编辑您的朋友列表?/users/{id}/friends/edit可以工作,但它似乎不合适,因为你永远不应该编辑别人的朋友列表。会/account/friends/edit是更好的选择吗?你会把相应的代码放在哪里?在朋友控制器、用户控制器或专用帐户控制器中?

额外的问题:你更喜欢哪个?/photos/delete/{id}或者/photos/{id}/delete


答案:

所以,我从答案中收集到的是,如果“事物”很复杂(如“朋友”)但没有自己的控制器,你可以给它一个没有模型的控制器,或者如果不是,你应该将与它最密切相关的东西塞进去。您的 URL 不应影响您放置代码的位置。大多数人似乎认为你应该尽可能坚持/controller/action/{id},因为这是人们所熟悉的。

除了说它“尴尬”之外,没有人真正评论扩展课程。如果我真的想把它分开,也许 FriendList 在这种情况下会是一个更合适的类。

感谢所有的答案 :)

4

5 回答 5

2

您正在谈论的路线,以及您使用子类来实现这种结构的方式,对我来说似乎有点尴尬。标准约定/controller/action/{id}非常适合简单的操作,但如果您正在创建一个复杂的应用程序,您将始终需要创建自定义路由。在创建这些路由时可能有一些很好的指导方针可以使用,但归根结底是在整个应用程序中保持一致并尽可能简单。

我认为没有任何充分的理由/user/{id}/friends映射到“ Friend”控制器。为什么不让“ friends”成为User控制器上的一个动作?一旦您真正深入查看特定朋友的页面,您可以使用Friend控制器 ( /friends/view/123),或者您可以重新调整User控制器的用途,使其适用于朋友或当前登录的用户 ( /user/view/123)。

回复:奖金问题,我会坚持使用/photos/delete/{id}/controller/action/{id}),因为这是最广泛接受的机制。

于 2009-06-22T22:00:03.093 回答
2

我宁愿/photos/{id}/delete. 我的理由是,如果你从 URL 的末尾去掉一个组件,它应该仍然有意义。

很容易假设/photos/{id}应该做什么:查看照片集{id}

但是应该/photos/delete怎么办?这还真不清楚。

我知道有一种默认约定/controller/action/id,但该组织是为了映射到控制器的类/方法架构。我认为组织 UI 以容纳代​​码并不是一个好主意(URL 在某种程度上是 UI 的一部分)。


回复评论:是的,/photos/{id}通过 id 查看给定照片可能更有意义。 /users/{id}/photos也许是为了查看收藏。由你决定。

关键是您应该从用户的角度考虑 UI,而不是从代码组织的角度考虑。

于 2009-06-22T22:01:21.393 回答
2

你可以做任何一个或。问题是当你将两者混合时。/users/{id}/friends 和 /users/friends/{id} 当某人的 id 为“friends”时,这将失败。这似乎是一个微不足道的案例,但使用用户名作为 id 非常流行。您必须限制每个操作的用户名。


有时你做不到/{controller}/{action}/{id}

不久前我做了一个独立音乐网站,我们做了

/artist/{username}
/artist/{username}/albums
/artist/{username}/albums/{album}

我们不想测试条件,所以我们没有这样做

/artist/{username}/{album}

因为我们不想检查任何拥有名为“albums”的专辑的人

我们本可以做到的

/artist/{username}
/artist/{username}/albums
/albums/{album}

但是这样我们就会失去在 URL 中同时包含艺术家姓名和专辑名称的 SEO 优势。同样在这种情况下,我们将强制专辑名称是唯一的,这会很糟糕,因为艺术家的专辑名称与其他艺术家相同是很常见的。

你可以做纯粹的/{controller}/{action}/{id},但你会失去一些搜索引擎优化,你不能做 URL 缩短。

/artist/view/{username}
/artist/albums/{username}
/album/view/{album}

回到你的例子。

/users/{id}/friends/edit 可以工作,但它似乎不合适,因为你永远不应该编辑别人的朋友列表。

在这种情况下,应该是/friends/edit因为您的用户 ID 是重复的信息,假设您以某种方式在会话中。通常,您希望支持 URL 缩短而不是 URL 扩展。

(奖金问题)我也不会使用RESTDELETE /photo?id={id}

于 2009-06-22T22:53:58.307 回答
1

它还取决于您存储数据的方式。我可以想象在某些情况下,您需要一个“朋友列表”作为模型中的实体。一个合乎逻辑的方法是为每个好友列表指定一个唯一标识符,一个主键。

这在逻辑上会导致以下路线,因为您只需要朋友列表的主键来编辑或删除它......

/friends/edit/{friendListId}

由您决定。正如 pix0r 所说:小型应用程序的约定是/{controller}/{action}/{id}{id} 应该是可选的以匹配您的大多数网站操作。在某些情况下,应用程序变得很大,并且您希望定义具有 3 个以上元素的特定路由。在某些情况下,某些实体只会获得更大的含义(上例),您可以决定为它定义一个自定义控制器(这使得默认路由再次完美......)。

我会坚持使用默认路由/controller/action/id,但不要一开始就开始为所有东西(比如朋友)制作控制器。模型-视图-控制器模式使您以后更改路由变得非常容易,只要您的所有路由链接和操作(表单等)都是基于路由和操作生成的。所以你真的不必那么麻烦:)

于 2009-06-22T22:19:18.407 回答
1

URL 本身并不重要。更重要的是每个控制器中的内容。在您的示例中,您的朋友列表扩展了User课程。如果您的朋友列表真的只是一个用户列表,也许它应该扩展Users控制器以便您在一个地方处理用户列表。

class Users {

    public function index() {
        $users = $this->findUsers();
    }

    protected function findUsers($userId=null) { ... }
}

class Friends extends Users {

    public function index($userId) {
        $users = $this->findUsers($userId);
    }
}

如果您很难确定要扩展哪个课程,请从每个课程中写出您需要的内容,然后选择列表最长的课程。

于 2009-06-22T23:28:46.893 回答