REST 流程图
本章将通过许多不同的图来解释REST处理程序状态机。
请求可以遵循四种主要路径。一个用于方法OPTIONS;一个用于方法GET和HEAD;一为PUT、POST、PATCH方法;一个用于方法DELETE。
所有路径都从“开始”图开始,如果资源存在,那么除了选项路径之外的所有路径都会经过“内容协商”图,或者可以选择的“条件请求”图。
红色方块代表另一个图表。浅绿色方块表示响应。其他方块可能是Cowboy自己应答的一个问题或回调。如果回调函数未定义,绿色箭头往往指示默认行为。值旁边的星号表示该值是描述性的,而不是精确的。
开始
所有请求都从这里开始.
连续调用一系列回调函数来执行对服务、请求行和请求报头的常规检查。
如果有请求主体,则预期不会为这些步骤中的任何一个接收到请求主体。只有在“PUT, POST和PATCH方法”图的末尾,当所有条件都满足时,才会处理它。
known_methods和allowed_methods回调函数返回一个方法列表。Cowboy然后检查请求方法是否在列表中,否则停止。
可以使用is_authorized回调函数检查对资源的访问是否被授权。也可以根据需要执行身份验证。当拒绝授权时,来自回调的返回值必须包括一个适用于所请求资源的问题,该问题将在www-authenticate报头中发送回客户机。
当请求方法是OPTIONS时,紧跟着这个图的是“OPTIONS方法”图,否则紧跟着的是“内容协商”图。
OPTIONS 方法
此图仅适用于OPTIONS 请求。
options
回调可用于添加有关资源的信息,例如所提供的媒体类型或语言;允许的方法;任何额外的信息。也可以设置响应主体,但不应期望客户端读取响应主体。
如果没有定义options回调,Cowboy将发送一个默认包含允许方法列表的响应。
内容协商
此图适用于除选项之外的所有请求方法。它在“开始”图完成后立即执行。
这些步骤的目的是确定发送回客户机的适当表示。
请求可以包含任何accept报头;accept - language报头;或者accept-charset报头。出现时,Cowboy将解析报头,然后调用相应的回调函数来获取为该资源提供的内容类型、语言或字符集的列表。然后它会根据请求自动选择最佳匹配。
如果没有定义回调,Cowboy将选择客户端喜欢的content-type、language 或charset 。
content_types_provided也会为它接受的每个content-type返回回调的名称。这个回调函数只会在“GET和HEAD方法”图的最后被调用,当所有的条件都满足的时候。
所选的内容类型、语言和字符集作为元值保存在Req对象中。如果您手动设置了响应主体(例如,伴随着错误代码),则应该使用适当的表示。
这个图紧接着是“GET和HEAD方法”图,“PUT, POST和PATCH方法”图,或者“DELETE方法”图,这取决于方法。
GET 和 HEAD 方法
此图仅适用于GET和HEAD请求。
有关第二个步骤的描述,请参见“条件请求”图。
当资源存在,且条件步骤成功时,可以检索资源。
Cowboy通过首先检索关于表示的元数据来准备响应,然后调用ProvideResource回调。这是为从content_types_provided返回的每个content-type定义的回调函数。这个回调函数返回将被发送回客户端的主体,如果体必须被流化,则返回一个函数的主体。
当该资源不存在时,Cowboy将查明该资源以前是否存在,如果存在,它是否被移动到其他地方,以便将客户端重定向到新的URI。
如果资源确实被移动了,那么moved_permanent和moved_temporary回调函数必须返回资源的新位置。
PUT, POST 和 PATCH 方法
此图仅适用于PUT、POST和PATCH请求。
有关第二个步骤的描述,请参见“条件请求”图。
当资源存在时,首先执行条件步骤。当成功并且方法是PUT,Cowboy将调用is_conflict回调函数。这个函数可以用来防止潜在的竞争条件,例如通过锁定资源。
然后这三个方法都达到了content_types_accepted步骤,我们将在几段中描述这个步骤。
当资源不存在,并且方法是PUT时,Cowboy将检查冲突,然后进入content_types_accepted步骤。对于其他方法,Cowboy将查明该资源以前是否存在,如果存在,是否被转移到其他地方。如果资源确实不存在,方法是POST并且allow_missing_post的调用返回true,那么Cowboy将继续执行content_types_accepted步骤。否则,请求处理将在那里结束。
如果资源确实被移动了,那么moved_permanent和moved_temporary回调函数必须返回资源的新位置。
content_types_accepted返回它所接受的content-type列表,以及每个content-type的回调名称。Cowboy将选择适当的回调来处理请求主体并调用它。
这个回调函数可以返回三个不同返回值中的一个。
如果在处理请求主体时发生错误,则必须返回false, Cowboy将发送适当的错误响应。
如果方法是POST,那么您可以返回true,并提供创建资源的URI。这对于为集合编写处理程序特别有用。
否则,返回true表示成功。Cowboy将选择要发送的适当响应,这取决于是否创建了资源,而不是修改了资源,以及响应中位置报头或主体的可用性。
DELETE 方法
此图仅适用于DELETE 请求。
有关第二个步骤的描述,请参见“条件请求”图。
当资源存在,且条件步骤执行成功时,可以删除该资源。
删除资源需要两个步骤。首先执行回调函数delete_resource。使用这个回调来删除资源。
由于资源可能被缓存,所以您还必须删除系统中该资源的所有缓存表示。不过,这个操作可能需要一段时间,因此您可能会在它完成之前返回。
然后Cowboy将调用delete_completed回调函数。如果您知道资源已经从您的系统中(包括从缓存中)完全删除,那么您可以返回true。如果任何疑问仍然存在,则返回false。Cowboy将默认为真。
最后,Cowboy检查是否设置了响应主体,并根据此情况发送适当的响应。
当该资源不存在时,Cowboy将查明该资源以前是否存在,如果存在,它是否被移动到其他地方,以便将客户端重定向到新的URI。
如果资源确实被移动了,那么moved_permanent和moved_temporary回调函数必须返回资源的新位置。
条件请求
此图适用于除OPTIONS之外的所有请求方法。当资源存在时,它会在resource_exists回调之后执行。
请求将会变成条件当它包含 if-match报头,if-unmodified-since报头;if-none-match报头;if-modified-since报头中的任何一个时。
如果条件失败,请求立即结束,不需要对资源进行任何检索或修改。
根据需要调用generate_etag和last_modified。Cowboy只会调用它们一次,然后缓存结果供后续使用。