From eeffca40eb9c40cc3b7ac61d7eaa7426d14b0bb3 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 9 Jun 2016 20:59:57 +0100 Subject: [PATCH] Tutorial updates --- docs/img/corejson-format.png | Bin 0 -> 20499 bytes docs/index.md | 1 + .../7-schemas-and-client-libraries.md | 88 +++++++++++++++--- mkdocs.yml | 1 + rest_framework/routers.py | 2 +- runtests.py | 2 +- 6 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 docs/img/corejson-format.png diff --git a/docs/img/corejson-format.png b/docs/img/corejson-format.png new file mode 100644 index 0000000000000000000000000000000000000000..36c197a0d02a78fa165f3cd123343ca87a27f102 GIT binary patch literal 20499 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 W6-VWcKNo4ud8WozM*kXmru+}qf?_iO literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md index 9204a4f11..fe7abf031 100644 --- a/docs/index.md +++ b/docs/index.md @@ -292,6 +292,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [tut-4]: tutorial/4-authentication-and-permissions.md [tut-5]: tutorial/5-relationships-and-hyperlinked-apis.md [tut-6]: tutorial/6-viewsets-and-routers.md +[tut-7]: tutorial/7-schemas-and-client-libraries.md [request]: api-guide/requests.md [response]: api-guide/responses.md diff --git a/docs/tutorial/7-schemas-and-client-libraries.md b/docs/tutorial/7-schemas-and-client-libraries.md index 62191ba63..7900d03f2 100644 --- a/docs/tutorial/7-schemas-and-client-libraries.md +++ b/docs/tutorial/7-schemas-and-client-libraries.md @@ -1,9 +1,26 @@ -# Tutorial 7: Schemas & Client Libraries +# Tutorial 7: Schemas & client libraries -An API schema is a document that describes the available endpoints that -a service provides. Schemas are a useful tool for documentation, and can also -be used to provide information to client libraries, allowing for simpler and -more robust interaction with an API. +A schema is a machine-readable document that describes the available API +endpoints, their URLS, and what operations they support. + +Schemas can be a useful tool for auto-generated documentation, and can also +be used to drive dynamic client libraries that can interact with the API. + +## Core API + +In order to provide schema support REST framework uses [Core API][coreapi]. + +Core API is a document specification for describing APIs. It is used to provide +an internal representation format of the available endpoints and possible +interactions that an API exposes. It can either be used server-side, or +client-side. + +When used server-side, Core API allows an API to support rendering to a wide +range of schema or hypermedia formats. + +When used client-side, Core API allows for dynamically driven client libraries +that can interact with any API that exposes a supported schema or hypermedia +format. ## Adding a schema @@ -11,20 +28,57 @@ REST framework supports either explicitly defined schema views, or automatically generated schemas. Since we're using viewsets and routers, we can simply use the automatic schema generation. -To include a schema for our API, we add a `schema_title` argument to the -router instantiation. +You'll need to install the `coreapi` python package in order to include an +API schema. + + $ pip install coreapi + +We can now include a schema for our API, by adding a `schema_title` argument to +the router instantiation. router = DefaultRouter(schema_title='Pastebin API') -If you visit the root of the API in a browser you should now see ... TODO +If you visit the API root endpoint in a browser you should now see `corejson` +representation become available as an option. + +![Schema format](../img/corejson-format.png) + +We can also request the schema from the command line, by specifying the desired +content type in the `Accept` header. + + $ http http://127.0.0.1:8000/ Accept:application/vnd.coreapi+json + HTTP/1.0 200 OK + Allow: GET, HEAD, OPTIONS + Content-Type: application/vnd.coreapi+json + + { + "_meta": { + "title": "Pastebin API" + }, + "_type": "document", + ... ## Using a command line client Now that our API is exposing a schema endpoint, we can use a dynamic client -library to interact with the API. To demonstrate this, let's install the -Core API command line client. +library to interact with the API. To demonstrate this, let's use the +Core API command line client. We've already installed the `coreapi` package +using `pip`, so the client tool should already be available. Check that it +is available on the command line... - $ pip install coreapi-cli + $ coreapi + Usage: coreapi [OPTIONS] COMMAND [ARGS]... + + Command line client for interacting with CoreAPI services. + + Visit http://www.coreapi.org for more information. + + Options: + --version Display the package version number. + --help Show this message and exit. + + Commands: + ... First we'll load the API schema using the command line client. @@ -50,6 +104,8 @@ We can now interact with the API using the command line client: $ coreapi action list_snippets +## Authenticating our client + TODO - authentication $ coreapi action snippets create --param code "print('hello, world')" @@ -58,8 +114,14 @@ TODO - authentication ## Using a client library -TODO +*TODO - document using python client library, rather than the command line tool.* + +## Using another schema format + +*TODO - document using OpenAPI instead.* ## Customizing schema generation -TODO +*TODO - document writing an explict schema view.* + +[coreapi]: http://www.coreapi.org diff --git a/mkdocs.yml b/mkdocs.yml index 19d1b3553..551b6bcd2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -20,6 +20,7 @@ pages: - '4 - Authentication and permissions': 'tutorial/4-authentication-and-permissions.md' - '5 - Relationships and hyperlinked APIs': 'tutorial/5-relationships-and-hyperlinked-apis.md' - '6 - Viewsets and routers': 'tutorial/6-viewsets-and-routers.md' + - '7 - Schemas and client libraries': 'tutorial/7-schemas-and-client-libraries.md' - API Guide: - 'Requests': 'api-guide/requests.md' - 'Responses': 'api-guide/responses.md' diff --git a/rest_framework/routers.py b/rest_framework/routers.py index f3e4bc4ea..81f8f8c83 100644 --- a/rest_framework/routers.py +++ b/rest_framework/routers.py @@ -332,7 +332,7 @@ class DefaultRouter(SimpleRouter): for prefix, viewset, basename in self.registry: api_root_dict[prefix] = list_name.format(basename=basename) - view_renderers = api_settings.DEFAULT_RENDERER_CLASSES + view_renderers = list(api_settings.DEFAULT_RENDERER_CLASSES) if self.schema_title: assert coreapi, '`coreapi` must be installed for schema support.' diff --git a/runtests.py b/runtests.py index 31593c3b4..e97ac0367 100755 --- a/runtests.py +++ b/runtests.py @@ -14,7 +14,7 @@ PYTEST_ARGS = { FLAKE8_ARGS = ['rest_framework', 'tests', '--ignore=E501'] -ISORT_ARGS = ['--recursive', '--diff', '-p', 'tests', 'rest_framework', 'tests'] +ISORT_ARGS = ['--recursive', '--check-only', '-o' 'uritemplate', '-p', 'tests', 'rest_framework', 'tests'] sys.path.append(os.path.dirname(__file__))