教程 7:Schemas 和客户端库

schema 是一个机器可读文档,描述可用的 API 端点,它们的 URL 以及它们支持的操作。

Schemas 可以是自动生成文档的有用工具,也可以用来驱动可以与 API 交互的动态客户端库。

Core API

为了提供 schema 支持,REST framework 使用 Core API

Core API 是用于描述 API 的文档规范。它用于提供可用端点的内部表示格式和 API 公开的可能交互。它既可以用于服务器端,也可以用于客户端。

当使用服务器端时,Core API 允许 API 支持对各种 schema 或超媒体格式的渲染。

当使用客户端时,Core API 允许动态驱动的客户端库,可以与任何公开支持的 schema 或超媒体格式的 API 进行交互。

添加 schema

REST framework 支持显式定义的 schema 视图或自动生成的 schemas。由于我们使用视图集和路由器,因此我们可以简单地使用自动 schema 生成。

您需要安装 coreapi Python 包以便包含 API 模式。

  1. $ pip install coreapi

我们现在可以通过在我们的 URL 配置中包含一个自动生成的 schema 视图来为我们的 API 包含schema。

  1. from rest_framework.schemas import get_schema_view
  2. schema_view = get_schema_view(title='Pastebin API')
  3. urlpatterns = [
  4. url(r'^schema/$', schema_view),
  5. ...
  6. ]

如果你在浏览器中访问 /schema/ 端点,那么你现在应该看到 corejson 表示成为可选项。 f_34764973.png

我们还可以通过在 Accept 头中指定所需的内容类型来从命令行请求 schema。

  1. (env) fang@ubuntu:~/django_rest_framework/tutorial$ http http://127.0.0.1:8000/schema/ Accept:application/coreapi+json
  2. HTTP/1.1 200 OK
  3. Allow: GET, HEAD, OPTIONS
  4. Content-Length: 1893
  5. Content-Type: application/coreapi+json
  6. Date: Wed, 20 Jun 2018 10:44:13 GMT
  7. Server: WSGIServer/0.2 CPython/3.5.2
  8. Vary: Accept, Cookie
  9. X-Frame-Options: SAMEORIGIN
  10. {
  11. "_meta": {
  12. "title": "Pastebin API",
  13. "url": "http://127.0.0.1:8000/schema/"
  14. },
  15. "_type": "document",
  16. ...

默认的输出风格是使用 Core JSON 编码。

还支持其他架构格式,如 Open API (以前称为Swagger)。

使用命令行客户端

现在我们的 API 公开了一个 schema 端点,我们可以使用一个动态客户端库来与 API 进行交互。为了演示这一点,我们使用 Core API 命令行客户端。

命令行客户端可用作 coreapi-cli 软件包:

  1. $ pip install coreapi-cli

现在检查它在命令行上是否可用…

  1. (env) fang@ubuntu:~/django_rest_framework/tutorial$ coreapi
  2. Usage: coreapi [OPTIONS] COMMAND [ARGS]...
  3. Command line client for interacting with CoreAPI services.
  4. Visit http://www.coreapi.org for more information.
  5. Options:
  6. --version Display the package version number.
  7. --help Show this message and exit.
  8. Commands:
  9. action Interact with the active document.
  10. bookmarks Add, remove and show bookmarks.
  11. clear Clear the active document and other state.
  12. codecs Manage the installed codecs.
  13. credentials Configure request credentials.
  14. describe Display description for link at given PATH.
  15. dump Dump a document to console.
  16. get Fetch a document from the given URL.
  17. headers Configure custom request headers.
  18. history Navigate the browser history.
  19. load Load a document from disk.
  20. reload Reload the current document.
  21. show Display the current document.

首先,我们将使用命令行客户端加载 API schema。

  1. (env) fang@ubuntu:~/django_rest_framework/tutorial$ coreapi get http://127.0.0.1:8000/schema/
  2. <Pastebin API "http://127.0.0.1:8000/schema/">
  3. snippets: {
  4. list([page])
  5. read(id)
  6. highlight(id)
  7. }
  8. users: {
  9. list([page])
  10. read(id)
  11. }

我们还没有进行身份验证,所以现在我们只能看到只读端点,与我们如何设置 API 的权限一致。

让我们尝试使用命令行客户端列出现有的 snippets:

  1. (env) fang@ubuntu:~/django_rest_framework/tutorial$ coreapi action snippets list
  2. {
  3. "count": 4,
  4. "next": null,
  5. "previous": null,
  6. "results": [
  7. {
  8. "url": "http://127.0.0.1:8000/snippets/1/",
  9. "id": 1,
  10. "highlight": "http://127.0.0.1:8000/snippets/1/highlight/",
  11. "owner": "djrest",
  12. "title": "test one",
  13. "code": "hello, world",
  14. "linenos": false,
  15. "language": "abap",
  16. "style": "abap"
  17. },
  18. ...
  19. ]
  20. }

一些 API 端点需要命名参数。例如,为了要获取特定的高亮 HTML 表示的 snippet,我们需要提供一个 id。

  1. (env) fang@ubuntu:~/django_rest_framework/tutorial$ coreapi action snippets highlight --param id=1
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
  3. "http://www.w3.org/TR/html4/strict.dtd">
  4. <html>
  5. <head>
  6. <title>test one</title>
  7. <meta http-equiv="content-type" content="text/html; charset=None">
  8. <style type="text/css">
  9. td.linenos { background-color: #f0f0f0; padding-right: 10px; }
  10. span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
  11. pre { line-height: 125%; }
  12. </style>
  13. </head>
  14. <body>
  15. <h2>test one</h2>
  16. <div class="highlight"><pre><span></span><span class="nv">hello</span><span class="p">,</span> <span class="nv">world</span>
  17. </pre></div>
  18. </body>
  19. </html>

认证我们的客户端

如果我们希望能够创建,编辑和删除 snippets,我们需要进行有效性用户身份验证。在这种情况下,我们只使用基本的 auth。

请确保使用您的实际的用户名和密码替换下面的 <username><password>

  1. (env) fang@ubuntu:~/django_rest_framework/tutorial$ coreapi credentials add 127.0.0.1 djrest:aa112211 --auth basic
  2. Added credentials
  3. 127.0.0.1 "Basic ZGpyZXN0OmFhMTEyMjEx"

现在,如果我们再次获取 schema,我们应该能够看到一组完整的可用交互。

  1. (env) fang@ubuntu:~/django_rest_framework/tutorial$ coreapi reload
  2. <Pastebin API "http://127.0.0.1:8000/schema/">
  3. snippets: {
  4. list([page])
  5. create(code, [title], [linenos], [language], [style])
  6. read(id)
  7. update(id, code, [title], [linenos], [language], [style])
  8. partial_update(id, [title], [code], [linenos], [language], [style])
  9. delete(id)
  10. highlight(id)
  11. }
  12. users: {
  13. list([page])
  14. read(id)
  15. }

我们现在可以与这些端点进行交互。例如,要创建一个新的 snippet:

  1. (env) fang@ubuntu:~/django_rest_framework/tutorial$ coreapi action snippets create --param title="Example" --param code="print('hello, world')"
  2. {
  3. "url": "http://127.0.0.1:8000/snippets/6/",
  4. "id": 6,
  5. "highlight": "http://127.0.0.1:8000/snippets/6/highlight/",
  6. "owner": "djrest",
  7. "title": "Example",
  8. "code": "print('hello, world')",
  9. "linenos": false,
  10. "language": "python",
  11. "style": "friendly"
  12. }

并删除 snippet:

  1. (env) fang@ubuntu:~/django_rest_framework/tutorial$ coreapi action snippets delete --param id=6

除了命令行客户端之外,开发人员还可以使用客户端库与 API 进行交互。Python 客户端库是第一个可用的客户端库,并且计划很快发布 Javascript 客户端库。

有关自定义 schema 生成和使用 Core API 客户端库的更多详细信息,您需要参阅完整的文档。

回顾我们的工作

拥有非常小的代码量,现在我们有了一个完整的 pastebin Web API,它完全是 Web 可浏览的,包括一个模式驱动的客户端库,并完成了身份验证、每个对象权限和多个渲染器格式。

我们已经走过了设计过程的每个步骤,并且看到如果我们需要自定义任何东西,我们都可以按部就班的简单地使用常规的 Django 视图实现。

您可以在 GitHub 上查看最终的教程代码,或者在沙箱中试用一个实例。

勇往直前

我们已经到达了教程的最后。如果您想更多地参与 REST framework 项目,可以从以下几个地方开始:

  • 通过审查和提交问题,并提出拉取请求,为 GitHub 做出贡献。
  • 加入 REST framework 讨论组,并帮助构建社区。
  • 在 Twitter 上关注作者并打个招呼。

现在就去构建非常棒的东西吧。