在RESTful html应用程序中放置表单/替代视图的位置?

时间:2014-07-11 11:47:55

标签: html forms rest

让我们假设一个Web应用程序,每个URI为GET请求提供一个很好的html视图,并允许通过POST / PUT / PATCH / WHATEVER更新底层资源。

如何然后公开实际允许从浏览器执行此类请求的各种表单?更广泛的:假设我有相同资源的替代视图(可能还有HTML),我在哪里放这些?可以说,这些形式可以被视为替代观点,因此对更广泛的问题的答案将是理想的。


编辑:为了澄清,我的问题不是关于提供JSON或诸如此类的纯数据API,而是关于HTML应用程序(如Stackoverflow)。例如,您可以在/questions下获取问题集合,在/questions/24696982处获取此特定问题是有意义的。要让表单添加新问题,您必须使用/questions/ask,我不确定是否正常。那形成POST到/questions/ask/submit,这似乎是完全错误的。向该URL发出GET请求会产生404(如果有的话,它应该是405)。表单应该POST到/questions。我仍然想知道在RESTful系统中是否至少认为表单的URI是可接受的。

8 个答案:

答案 0 :(得分:5)

你有一个像这样的网站,构建一个真正的RESTFull API的一种方法是分割前端和API - 这在我看来是最好的方式(有些人可能不同意) - 也许其他人不这么认为但是我们可以说前端团队获得了www.domain,而您的API团队获得了api.domain

GET api.domain/questions - Retrieves a list of tickets   
GET api.domain/questions/12 - Retrieves a specific ticket   
POST api.domain/questions - Creates a new ticket  
PUT api.domain/questions/12 - Updates ticket #12  
DELETE api.domain/questions/12 - Deletes ticket #12  
PATCH api.domain/questions/12 - Partially updates ticket #12 #I only want to display that this also exists - i don't really use it...   

AWESOME EDIT:正如您所看到的,stackoverflow也使用此方法:api.stackexchange.com

因为您可以看到您可以拥有这些结构 - 但您也可以在www.domain/questions/ask上添加表单,此表单会通过api.domain/questions将请求发送到POST。我想参考:https://thenewcircle.com/s/post/1221/designing_a_beautiful_rest_json_api_video这是一个你应该听过的非常好的播客。

编辑:(另一种观点)

另一个想法是,如果您的客户端向您发送了正确的Accept-Header,您可以简单地选择应该返回的内容(Json,XML,HTML)。

示例1:

       URL           REQUEST       ACCEPT HEADER               RESPONSE                      
-----------------------------------------------------------------------------------------
domain/questions      GET        application/json   all questions as json
domain/questions      GET        text/html          the page as html with all questions
domain/questions/ask  GET        text/html          Your html for to add a new question
domain/questions      POST       application/json   Add a new new questions (this would be called from ./ask to add the new questions
domain/questions/ask  GET        application/json   404 Status-Code because on questions/ask you don't have implemented any resource

例2:

       URL              REQUEST     ACCEPT HEADER               RESPONSE                      
-----------------------------------------------------------------------------------------
domain/questions/12       GET      application/json   Shows the questions with the ID 12 as JSON
domain/questions/12       GET      text/html          Shows the HTML representation of your page
domain/questions/12/edit  GET      text/html          Your html for to edit a the question
domain/questions/12       PUT      application/json   Updates the questions with the ID 12 // just to add the PATCH thing.. i don't really use it but if you don't update the whole object you could/should use PATCH instead of PUT :p
domain/questions/12/edit  GET      application/json   404 Status-Code because on questions/ask you don't have implemented any resource

昨天我告诉了你关于第一个想法(这是 - 我认为使用api作为一个团队(一个用于前端和一个开发api的团队 - 一个更好的方法)但是@jackweirdy评论(感谢你 - 然后我搜索了很多,正在寻找世界各地的开发者的其他播客,以及他们将如何做到这一点)下面真的由你决定 - 这是你的api,最后你/你的团队将决定一个方向。希望这个帮助您或其他寻求如何在REST背景上构建API的人。

EDIT-Section中的示例(如果我做对了)不像stackoverflow那样

答案 1 :(得分:1)

这是我自己遇到麻烦的事情,而且我认为没有正确答案。

假设我有一个公开/people/:id的API,我通常会为/people/new保留一个端点。对具有GET的网址发出Accept: text/html请求将返回创建表单,但其他任何内容都会返回404,因为此页面仅适用于网络浏览器中的用户。然后,该页面上的表单会按照您的预期发布到/people/

同样,如果有人想要修改现有的人,那么可以从/people/1/update提供表单来执行该操作,同样只提供HTML。

如果您的API具有该结构,那么我认为保留newupdate等关键字是完全合理的。

答案 2 :(得分:0)

在100%RESTful Web服务资源中使用描述性URL进行标识,即仅由名词短语组成的URL。

通常来说,对于创建新资源,您将使用PUT,尽管某些框架(例如Zend Framework 2,如果我记得很清楚),为此目的使用POST。因此,要创建问题,您可以PUT questions,然后在请求正文中提供问题标识符,或PUT questions/{identifier},从而在网址中提供ID。

答案 3 :(得分:0)

REst的本质绝不是关于URL的样子,而是如何使用http动词和标题来传输数据。

这整个" restfull urls"事情是由不了解休息的人组成的。所有Rest规范都说URL必须是唯一的。

现在,如果你真的想要" restfull"表单,然后表单应该是一个具有id的资源,如/ form / 2929929。当然这样做没有意义,因为表单是严格意义上的网络用户和REst不关心如何获取数据,只关心它是如何转移。

简而言之,选择您想要的任何网址。一些框架使用new和表单更新。顺便说一下/ questions / ask / submit在Rest语境中是完全有效的,因为你提交的内容和问题可以是2个完全不同的资源。

答案 4 :(得分:0)

据我所知,您需要一个应用程序:

  • 显示HTML页面(最终显示其他格式?)
  • 显示用于创建新元素或更新现有元素的表单视图
  • 接受带有url编码数据的POST / PUT(通过提交上述表单发送)来创建更新这些元素(最终是其他格式?)

Ruby on Rails是一个以此类要求为目标的框架。指南摘录Rails Routing from the Outside In

HTTP Verb   Path            action      used for
GET        /photos          index       display a list of all photos
GET        /photos/new      new         return an HTML form for creating a new photo
POST       /photos          create      create a new photo
GET        /photos/:id      show        display a specific photo
GET        /photos/:id/edit edit        return an HTML form for editing a photo
PUT        /photos/:id      update      update a specific photo
DELETE     /photos/:id      destroy     delete a specific photo 

您可以为操作索引,新建,显示和编辑提供HTML视图。

就个人而言,我建议添加以下内容:

POST       /photos/:id        update    update a specific photo
POST       /photos/:id/delete destroy   delete a specific photo

这样通过html表单更新或删除元素会更简单。

所有这些路径都只是Rails约定,并不是由REST强加的,但它提供了一个可以完成的工作的简洁示例。

但是使用其他框架使应用程序遵循相同或稍微不同的约定是非常容易的。 Java + Spring MVC可以非常轻松地使用JSP,Velocity,Thymeleaf或其他HTML视图,以及在URL(GET /photos/:id.json)中使用HTTP头或后缀的输入或输出中使用JSON的可能性比RoR更少魔法但更有控制力。而且我不是Struts2(仍然是Java)或Django(Python)等其他框架的专家,但我很确定它也是可行的。

重要的是:

  • 选择一种语言(Ruby,Python,Java,PHP,ASP.NET,...)
  • 选择与RESTfull网址兼容的框架
  • 通过添加后缀或HTTP标头以及最终适当的适配器/转换器
  • ,确保您可以使用HTML或JSON视图或输入所需的格式

您可以手动 ,但框架限制了锅炉板代码。

答案 5 :(得分:0)

您需要了解RESTfull应用程序和REST客户端之间存在差异。

RESTfull应用程序具有您所描述的纯粹的restfull URL,例如

GET     /persons   : gets a list of all the persons in database
POST    /persons   : adds a new person
GET     /person/1  : gets a person with id 1
PUT     /person/1  : updates person with id 1
DELETE  /person/1  : deletes person with id 1

依旧......

此类应用程序没有任何表单或用于提交数据的UI。它仅通过HTTP请求接受数据。要使用此类应用程序,您可以使用 curl 等工具发送和接收数据,甚至可以使用浏览器来发送和接收数据。

现在,从用户的角度来看,显然这样的应用程序是不可用的。因此,我们需要创建使用这些restfull应用程序的客户端应用程序。这些客户根本没有休息,并且有以下网址:

GET     /person/showall  : displays a list of all persons
GET     /person/create   : shows new person form
POST    /person/create   : submits the data to the restfull application via ajax or simillar technology.

依旧......

这些客户端可以是另一个HTML应用程序,一个Android应用程序,一个iOS应用程序等。

你在这里要做的是创建一个单独的应用程序,它既有对象的restful url,也有数据显示和输入的表单/页面。 这绝对没问题。

只需确保为您的对象设计适当的restfull网址,同时您可以找到适合您的表单的任何网址。

答案 6 :(得分:0)

当代网络/云应用程序已经转向所谓的单页面应用程序架构。

此体系结构具有后端REST API(通常基于JSON),然后由单个页面应用程序或移动电话和平板电脑上的本机客户端应用程序使用。然后,无论是Web客户端还是本机手机/平板电脑平台,服务器都更容易实现和扩展,并提供所需的访问权限。

客户端体系结构被称为MV * for Model,View和*是框架提供的任何其他内容,例如控制器逻辑和持久性。

在我的应用程序中,我愤怒地使用了许多MV *框架和库,并调查了很多。我已经在骨干和我最喜欢的Ember.js上取得了一些成功,虽然有很多框架,每个人都有自己喜欢的不同原因,这本身就是一个完整的话题。我会说,根据应用程序的需要,不同的框架或多或少都是合适的。我知道对我的工作效率有什么影响所以我在完成这些工作后已经确定了Ember。

在后端,您有类似的无数选择,但选择一个已知成熟且稳定的平台,同样适用于您的数据持久性。有许多云服务可以为您提供REST / JSON API,而不需要编码或部署问题,因此您可以将更多精力放在客户端开发上,而不是服务器上。

重要的是要理解,在单页面应用程序中,浏览器URL不需要与后端rest api具有1对1的对应关系。事实上,采用这种简单的方法对可用性是不利的。在所有客户端框架中,Ember因为它具有内置路由器而得到了正确的结果,因此客户端状态被捕获在URL中,因此页面可以在刷新后存活并且也可以被加入书签。您真的可以使您的客户端视图独立于后端api端点。我在表单的菜单/结构周围设计了我的客户端URL。在复杂的应用程序中,URL嵌套到我需要应用程序进行分区和深入细节,但api端点是扁平的,可能跨越多个服务提供商。我的客户端应用程序中的视图通常汇集来自多个端点的数据,类似地,接受/保存它会推送到多个端点。还可以实现本地持久性,以便可以脱机使用Web客户端,以便临时或半填充的表单可以在页面刷新后继续存在。

这种架构的另一个考虑因素是SEO。对于单页面应用程序,需要能够为Web爬网程序提供预呈现页面。幸运的是,有许多工具可以为单页面应用程序自动生成页面,这样网页抓取工具仍可以为您的网站内容编制索引,pretender.io等工具可以为您解决此问题。

在所有这些结束时,您的服务器具有许多REST端点,通常是单个index.html,app.js app.css以及任何其他资产,如图像和字体。

通常,您需要一个工具链来从源代码生成这些文件,然后这些文件将托管在您的域或CDN上。我还为CORS配置了我的应用程序和服务器,因此Web客户端可以托管在REST后端的不同域上,这也适用于开发。

我推荐使用西兰花或ember-cli工具链来组装您的所有网络客户资产,我也有很好的Brunch经验。我已经尝试了大部分工具,而且这些工具是唯一获得我投票的工具。

对于API设计,我一直积极提供有关JSON API最新草案的反馈。那里有很多好的工作,你可以把它作为一个很好的起点。

答案 7 :(得分:0)

通常在生产Web应用程序中,我建议分离静态内容的交付方式与交付动态内容的方式。

让我们希望您不受SEO限制,并且实际上可以使用DOM操作的奇迹(即客户端模板)......

我强烈建议您学习如何创建SPA(单页应用程序)

然而,回到手头的话题。

静态内容(HTML,CSS,Javascript,图像)应通过与动态内容不同的服务器(json / xml格式的REST数据)提供。

您的HTML应该使用JQuery / AngularJS / Backbone - 某种类型的JavaScript框架,可以使用JavaScript在客户端实际“呈现”您的HTML。

JavaScript框架还将对POST或PUT表单进行适当的RESTful调用(应该是某些REST路径的UI表示)

假设您有个人资料的表单,

GET /profile/{id}  would be called to pre-populate a profile FORM

PUT /profile/{id}  would be called to update the profile 

** JavaScript将通过调用一个或多个RESTful GET方法预先填充FORM。

** JavaScript将从FORM输入数据并将其发送到RESTful服务器。

你应该从中得到的一点是:

让高级JavaScript库处理RESTful请求的发送和HTML的“呈现”。

HTML只是一个模板(静态内容),可以托管在完全不同的服务器上,该服务器针对提供“静态内容”的工作进行了优化:)

希望这是有道理的。

干杯!

P.S。    如果您还没有,请了解跨源资源共享(CORS)。您可能需要这些知识才能在不同于动态内容的服务器/域上正确托管静态内容。