带类别的RESTAPI设计

带类别的RESTAPI设计,rest,api-design,Rest,Api Design,假设有一个移动应用程序可以接收各种类型的通知(如WhatsApp通知、Facebook Messenger通知等)。对于这一点,什么是更好的RESTAPI结构 /users/test@abc.com/notifications //Gives all the notifications 以下两种格式在使用方式上存在混淆 /users/test@abc.com/notifications?category=whatsapp,facebook //Gives all the notifica

假设有一个移动应用程序可以接收各种类型的通知(如WhatsApp通知、Facebook Messenger通知等)。对于这一点,什么是更好的RESTAPI结构

/users/test@abc.com/notifications //Gives all the notifications
以下两种格式在使用方式上存在混淆

/users/test@abc.com/notifications?category=whatsapp,facebook    //Gives all the notifications
vs

/users/test@abc.com/notifications/whatsapp  //Gives only whatsapp notification
/users/test@abc.com/notifications/facebook  //Gives only facebook notification
/users/test@abc.com/notifications/{notification-id}
访问单个通知资源的步骤

/users/test@abc.com/notifications/facebook/{notification-id}
vs

/users/test@abc.com/notifications/whatsapp  //Gives only whatsapp notification
/users/test@abc.com/notifications/facebook  //Gives only facebook notification
/users/test@abc.com/notifications/{notification-id}

如果一个资源有一个唯一的ID,那么它应该可以直接从那个ID访问,所以在我看来

/notifications/{id}
这很有道理。就过滤而言,这可能更多地是关于偏好。以下是我认为最惯用的方法

/notifications    // fetch all notifications
/notifications/facebook    // fetch all Facebook messages
/notifications/whatsapp    // fetch all WhatsApp messages
/users/{id}/notifications    // fetch user notifications 
/users/{id}/notifications/facebook    // fetch user Facebook notifications 
/users/{id}/notifications/whatsapp    // fetch user WhatsApp messages

这实际上取决于您如何定义
通知
资源及其与
类别
类型的关系(
whatsapp
facebook
…)

类别
相关 如果通知的结构不依赖于其类别,则您希望在没有任何类别上下文的情况下访问该通知:

/users/test@abc.com/notifications/{notification-id}
您可以将该类别用作通知集合的筛选器:

/users/test@abc.com/notifications?category=whatsapp,facebook
类别
相关 否则,如果通知在结构上取决于其类别(例如,如果您希望在处理
whatsapp
通知时定义不同于处理
facebook
通知时的操作),则您可能希望根据其类别区分通知:

/users/test@abc.com/notifications/whatsapp/{whatsapp-notification-id}
/users/test@abc.com/notifications/facebook/{facebook-notification-id}
在这种情况下,您可以:

/users/test@abc.com/notifications/whatsapp/1
/users/test@abc.com/notifications/facebook/1
定义两个不同的通知(尽管它使用相同的标识符)

现在请求此类通知的集合与之前的“非类别相关”情况略有不同

如果您只想获得
whatsapp
通知,则只需调用类别资源即可:

/users/test@abc.com/notifications/whatsapp
但是,如果要搜索不同的类别,则不能将请求应用于特定的类别资源。事实上,当你处理
whatsapp
通知时,要求
facebook
通知是没有意义的:

/users/test@abc.com/notifications/whatsapp?category=facebook # weird
一种解决方案是根据请求的类别提出尽可能多的请求:

/users/test@abc.com/notifications/whatsapp
/users/test@abc.com/notifications/facebook
但是,您以后必须合并您的结果

另一个解决方案是直接从应用查询

/users/test@abc.com/notifications?category=whatsapp,facebook

但结果将不同于“非类别依赖”情况。事实上,您将无法直接获得通知列表,而是可以访问通知列表的类别列表。

您是否看过这个:问题不同。这是一个更好的方法,在URL中使用查询参数与路径如果我必须在一个请求中提到多种类型,如“facebook”、“whatsapp”、“gmail”,那么使用这种方法会很困难,对吗?如果两者都得到支持会更好吗?比如?types=facebook,whatsapp和notifications/whatsapp,notifications/facebook。@因此,如果希望您提取多个类型,但不是所有类型,那么是的,查询字符串参数将是更好的选择。。。但就我个人而言,我不会有多种方法来做同一件事,在我看来,API中的一致性很重要。因此,如果你的想法是你可以选择一种或多种类型,我建议你选择
?filter=facebook,whatsapp
,以及单选
?filter=facebook
等。