【问题标题】:How do REST URIs work internally?REST URI 在内部是如何工作的?
【发布时间】:2012-06-13 18:48:22
【问题描述】:

我正在尝试创建一个 REST API 来与 MySQL 数据库交互。我想使用此 API 从 Android 或 iOS 设备访问数据库,而无需(显然)直接通过应用程序公开数据库。但是我在思考关于 REST 的一个关键方面以及根据其原则设计的 API 的实现时遇到了问题。

我从理论的角度理解 REST 的概念。几天来我一直在努力理解的是REST URI 如何映射到位于数据库服务器上的东西。

如果我向服务器发出 GET 请求以获取具有给定 URI 的资源,例如 http://www.example.com/resource,在内部,它会在服务器上的哪个位置发送?我理解它的方式是它进入根目录,然后进入“资源”目录。从那里它返回该“资源”目录中的所有文件。我只是感到困惑,因为资源位于数据库服务器上,而不是从中调用 API 的服务器上。资源路径/层次结构是代表服务器上的实际目录还是资源的抽象?如果是后者,那么我该如何处理该抽象资源名称以使其映射到数据库中的表或行?找不到具体的实现示例,我可以很容易地理解这个 URI 路径在内部是如何工作的,这令人沮丧。

【问题讨论】:

  • 请提出更具体的问题。这太开放了,问了太多问题。
  • 我认为这不值得反对。当然,这个问题很模糊,但这并不是因为问题中缺乏信息。提问者只是对 RESTful 思维方式感到困惑,并要求对其进行澄清。似乎他在问之前已经做了相当多的研究,但没有完全理解 RESTful API 的含义。

标签: android ios api rest


【解决方案1】:

您可以使用框架为您完成很多工作,但在后台发生的事情并不是什么神奇的事情。在某种程度上,URI 映射到一些数据库表。它们不是指某个目录结构,而是试图解释资源之间的层级关系。

例如,假设我们正在为一所大学建模。数据库中的元素存储在 FacultiesCourses 两个表之一中。 Faculties 表由描述法学院、医学院等的行组成。它有一个独特的 faculty_id 列,然后是用于描述我们需要的任何内容的列。 Courses 表有一个唯一的 course_id 列和一个外键 faculty_id 列,以告知该课程属于哪个学院。

设计此 API 的 RESTful 方式可能是

  • /faculties 获取所有院系的列表,使用 SELECT * FROM Faculties 检索
  • /faculties/2获取某院系的信息,用SELECT * FROM Faculties WHERE faculty_id=2检索
  • /faculties/2/courses获取属于某个学院的所有课程,用SELECT * FROM Courses WHERE faculty_id=2检索
  • /faculties/2/courses/15检索某个课程,如果确实属于教员2,使用SELECT * FROM Courses WHERE faculty_id=2 AND course_id=15检索

具体实现取决于您选择的编程语言(可能还有框架),但有时您需要选择查询数据库的方式。这并不明显。您需要仔细计划它才有意义!

当然,来自数据库的结果必须以某种方式编码,通常是 XML 或 JSON(但其他表示形式也一样好,虽然可能不那么常见)。

除此之外,您还应该确保正确实现这四个动词,以便它们与 SQL 命令匹配(GET=SELECTPOST=INSERTPUT=UPDATEDELETE=DELETE),正确处理编码协商,返回正确的 HTTP 响应代码以及 RESTful API 所期望的所有其他内容。

作为最后一条建议:如果您能巧妙地做到这一点,那么您设计移动应用程序将变得轻松得多。我真的不能强调这一点。例如,如果您在 POST 请求中返回现在在数据库中查看的完整条目,您可以立即使用正确的 ID 将其存储在手机上,并且您可以使用相同的代码来呈现内容如果它是使用GET 请求下载的。此外,在您知道请求是否成功之前,您不会通过过早更新来欺骗用户(手机经常失去连接)。

编辑:在 cmets 中回答您的问题:创建 API 可以被视为一种艺术形式,并且可能不应该在设计阶段涉及任何编码。 API 应该是有意义的,并且不依赖于特定的实现(即不同的数据库选择不应该影响您的 API)。您的下一个任务将是在 API 的人类可读结构和您的数据库之间建立联系(无论它是关系型还是其他)。所以是的,你需要做一些翻译,但我看不出查询字符串对你有什么帮助。典型的结构是api.my.website/collection/element/collection/element。查询可用于过滤。例如,您可以编写 example.com/resource?since=2012-06-01 以从您的“资源”集合中检索元素的子集,但此特定查询的含义是检索您无法用唯一 ID 表达的内容。

按照我的理解,您认为传入的请求必须始终根据 PHP 和 HTTP 服务器的工作方式转到单独的文件。这不是的情况。你可以configure your web server to route every request to a single PHP file,然后解析$_SERVER['REQUEST_URI']。根据您选择的 HTTP 服务器,您的工作量可能会有所不同,但这基本上是您想要做的。

通过谷歌搜索,我找到了a list of frameworks for PHP,但我一个都不认识。不过还有其他人,我最近也听到有人提到Apify,尽管我也不能告诉你太多。 PHP 可能是实现 API 的更常见的选择之一。然而,cURL 是一个库/工具,据我所知,它仅用于连接到其他 网站。你当然可以使用the command line version of it 来调试你的API,但我认为你在服务器端用处不大。

【讨论】:

  • 非常感谢您的帮助!再澄清一点:按照您描述的方式,这就是我的意思,似乎我必须以某种方式将 URI 转换为可用数据来执行查询。那么这是否类似于将我原来的示例说example.com/resource/23 翻译成example.com/resource?resource-id=23?如果是这样,那是从某个语言库完成的还是我必须实现的?我正在使用 PHP 来实现并研究了 cURL。那会是我用来做那种事情的东西吗?
  • @Perley:我的回复太长,无法放入评论;检查我对答案所做的编辑。如果您需要更多帮助,请告诉我。祝你好运!
  • 再次非常感谢您,您的帮助很大。在我问完之后,我立即搜索了将 URI 解析到我的服务器的方法,发现我确实只需要获取 API 表单的任何 URI 并将其重新路由到解析它并变成某种东西的处理程序对 API 使用有意义。但是我不完全确定如何去做。当您不完全确定时,很高兴得到确认。因此,我再次感谢您的所有帮助。
【解决方案2】:

我认为您应该从要构建 REST 应用程序的框架开始。 Rails、RestEasy for java、Codeigniter,都具备良好的 REST 路由能力的基础。 这包括从数据库甚至业务流程的下划线资源中提取 URL。他们使用 URL 映射或为抽象创建外观来完成此操作。
通常 REST 与带有查询参数的传统 GET/PUT/POST 并没有真正的区别。事实上,Apache URL 重写通常用于支持 REST 风格的路由。我建议您应该选择其中一个框架并研究它们如何实现此功能。 Rails i 的东西在其他框架中具有显着的优势。

【讨论】:

  • 这样的回答我的问题。现有的框架是 Drupal(我没有选择)。那么,这仅仅是使用他们对 REST(或 SOAP 相关)的任何支持围绕框架构建服务的做法吗?如果这都是一堆愚蠢的问题,我很抱歉,因为细节的婚礼发展对我来说是新的。我只是喜欢完全了解事物的运作方式,而不是从表面上接受它们。
猜你喜欢
  • 1970-01-01
  • 2015-03-01
  • 2021-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多