简体   繁体   English

REST - 为当前用户获取资源的 API 设计

[英]REST - API design to get resources for current user

We have a FitnessClassesService which allows scheduling fitness-training classes.我们有一个FitnessClassesService ,它允许安排健身训练课程。 There are a number of actors for every class:每个班级都有许多演员

  • The main trainer who explains the entire workout - he does all the talking but does not necessarily do the workouts himself.解释整个锻炼过程的主要教练- 他负责所有的谈话,但不一定自己进行锻炼。
  • A substitute trainer in case the main trainer is not available主教练不在时的替代教练
  • Two trainers who demonstrate the entire workout by actually doing it in the class - one for the newbies and one for old-timers两位教练通过在课堂上实际进行演示来展示整个锻炼过程 - 一位针对新手,一位针对老手
  • Two trainers who just move around the class to clarify any doubts.两个培训师只是在课堂上走动以澄清任何疑问。

When a class is created, all the actors are also added to it.当一个类被创建时,所有的演员也被添加到其中。 The trainers have an app from where they can see the classes which they have to participate in today (in any role).培训师有一个应用程序,从那里他们可以看到他们今天必须参加的课程(以任何角色)。

I create classes by calling POST /classes .我通过调用POST /classes创建POST /classes

What would be the correct REST API for getting all classes for a trainer when they open their app.当培训师打开他们的应用程序时,获取所有课程的正确 REST API 是什么? These are the alternatives I considered:这些是我考虑的替代方案:

  • Get /classes - Get userId from the HTTP header and use that to get classes for the current logged-in user only. Get /classes - 从 HTTP 标头获取 userId 并使用它来获取仅当前登录用户的类。 However, this does not seem very RESTful to me.但是,这对我来说似乎不是很 RESTful。
  • GET /classes/~alice or Get /classes/current - From designing-uri-for-current-logged-in-user-in-rest-applications . GET /classes/~aliceGet /classes/current - 来自design-uri-for-current-logged-in-user-in-rest-applications This will only get classes represented by the " current " user.这只会获取由“当前”用户表示的类。 However, unlike the example in the linked question where " users " was a resource and the " current " user represented a specific resource, I don't feel like " current " represents a resource for my usecase.但是,与链接问题中“用户”是资源而“当前”用户代表特定资源的示例不同,我不觉得“当前”代表我的用例的资源。 " current " for me represents all classes where I am an interested party. 当前”对我来说代表所有我感兴趣的班级。 This sounds like I have to filter on the classes resource instead of asking for a specific resource.这听起来像我必须filter classes资源而不是请求特定资源。
  • GET /classes?actorId=alice or GET /classes?actorId=current - But what if someone calls GET /classes . GET /classes?actorId=aliceGET /classes?actorId=current - 但是如果有人调用GET /classes Should I verify that an actorId must always be passed.我是否应该验证必须始终传递 actorId。 Additionally, the actorId must match the logged-in user's id.此外,actorId 必须与登录用户的 ID 匹配。 Is it okay to do such authorization based on URI parameters.是否可以根据 URI 参数进行此类授权。
  • Get /myclasses - Use a different URI. Get /myclasses - 使用不同的 URI。 This means that I will be creating classes by POST /classes but getting classes by a different URI.这意味着我将通过POST /classes创建类,但通过不同的 URI 获取类。

What would be the canonical way of handling this.处理这个问题的规范方法是什么。

What would be the correct REST API for getting all classes for a trainer when they open their app当培训师打开他们的应用程序时,获取所有课程的正确 REST API 是什么?

If you want a REST API, an early step is to think carefully about your resources .如果您需要 REST API,那么早期的步骤是仔细考虑您的资源

Any information that can be named can be a resource: a document or image, a temporal service (eg "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (eg a person), and so on.任何可以命名的信息都可以是资源:文档或图像、时间服务(例如“洛杉矶今天的天气”)、其他资源的集合、非虚拟对象(例如人)等. In other words, any concept that might be the target of an author's hypertext reference must fit within the definition of a resource.换句话说,任何可能成为作者超文本引用目标的概念都必须符合资源的定义。

Conceptually, "Alice's schedule" and "Bob's schedule" are resources.从概念上讲,“Alice 的日程安排”和“Bob 的日程安排”是资源。 So too is "MY schedule", but of course we have a pronoun antecedent problem. “我的时间表”也是如此,但当然我们有一个代词先行问题。

There are two pretty straight forward ways to handle an authenticated request for "my schedule";有两种非常直接的方法可以处理对“我的日程安排”的经过身份验证的请求; you can respond by redirecting to the correct resource, and you can inline the current representation of the correct resource into your response (with metadata indicating where it came from).您可以通过重定向到正确的资源来响应,并且可以将正确资源的当前表示内联到您的响应中(元数据指示它来自哪里)。 Those approaches are both fine .这些方法都很好

(Note: RFC 7234 constrains the caching of authenticated responses, which is part of why it is "fine"). (注意:RFC 7234 限制了经过身份验证的响应的缓存,这也是它“很好”的部分原因)。

REST doesn't care what spellings you use for your URI (so long as it conforms to the production rules defined in RFC 3986). REST 不关心您为 URI 使用的拼写(只要它符合 RFC 3986 中定义的生产规则)。 So all of these are fine所以所有这些都很好

/classes/actorId=alice
/classes?actorId=alice

/classes/alice
/classes?alice

Use a different URI.使用不同的 URI。

Still fine.还好。

One of the things that you need to be aware of is that cache invalidation is tied to the URI;您需要注意的一件事是缓存失效与 URI 相关; when you POST to /classes , it will invalidate your locally cached representation of /classes but not your locally cached representation of /myclasses .当你POST到/classes ,它会作废您的本地缓存表示/classes ,但不是你的本地缓存的代表性/myclasses Which means that when you have the same information encoded into the representations of multiple resources, those representations will not necessarily be synchronized.这意味着当您将相同的信息编码到多个资源的表示中时,这些表示不一定是同步的。

I PUT to /classes/{classId} , will it invalidate the cached response associated with /classes.我 PUT 到 /classes/{classId} ,它会使与 /classes 关联的缓存响应无效。 Similarly, if I POST to /classes, will it invalidate the cached response associated with /classes/alice同样,如果我 POST 到 /classes,它是否会使与 /classes/alice 关联的缓存响应无效

No to both.两者都没有。 The hierarchy implied by similar identifiers is not real.相似标识符所暗示的层次结构是不真实的。 You describe relationships between URI via link relations , not spelling, and there aren't currently standardized link relations that mean "these resources should be invalidated together".您通过链接关系而不是拼写来描述 URI 之间的关系,并且目前没有标准化的链接关系意味着“这些资源应该一起失效”。

When I PUT /classes/{classId}, shouldn't the cache for GET /classes be invalidated.当我 PUT /classes/{classId} 时,GET /classes 的缓存不应该失效。 Otherwise GET /classes may return a stale representation of /classes/{classId}否则 GET /classes 可能会返回 /classes/{classId} 的陈旧表示

As far as general purpose components are concerned, /classes/{classId} is completely unrelated to /classes .就通用组件而言, /classes/{classId}/classes完全无关。 Identifiers are identifiers , not "identifiers and also implicit link relations".标识符是标识符,而不是“标识符和隐式链接关系”。

The general purpose mechanism for describing a relationship between links is a link relation .用于描述链接之间关系的通用机制是链接关系 So if we wanted to announce to general purpose components that the changes to this resource also invalidate cached representations of that resource, we would need something like Linked Cache Invalidation .因此,如果我们想向通用组件宣布对该资源的更改也会使该资源的缓存表示无效,我们将需要类似Linked Cache Invalidation 的内容

But... that draft expired seven years ago without being adopted, and I haven't yet found a substitute for it.但是……那个草案七年前就过期了,没有被采纳,我还没有找到替代的。

Which in essence means that the limitations on cache invalidation are a constraint that you need to keep in mind when designing your resource model.这实质上意味着缓存失效的限制是您在设计资源模型时需要牢记的约束 If it's important that information A and information B get invalidated together, then they need to be modeled by the same resource.如果信息 A 和信息 B 一起失效很重要,那么它们需要由相同的资源建模。

Of course, you can including caching information in your payloads, so that custom clients can know that the data is invalid;当然,您可以在负载中包含缓存信息,以便自定义客户端知道数据无效; you express the link relation in your record schema, and clients that are aware of the schema can choose the appropriate action.您在记录模式中表达链接关系,了解模式的客户端可以选择适当的操作。 You can even lift that information from the body of the message to the headers, if you like.如果您愿意,您甚至可以将该信息从消息正文提升到标题。 But since none of the standard components know what your new header means, they all just ignore it (in other words, its just noise until we have a contract that both producers and consumers understand).但是因为没有一个标准组件知道你的新标头是什么意思,他们都只是忽略它(换句话说,它只是噪音,直到我们有一个生产者和消费者都理解的合同)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM