diff --git a/docs/img/corejson-format.png b/docs/img/corejson-format.png new file mode 100644 index 000000000..36c197a0d Binary files /dev/null and b/docs/img/corejson-format.png differ 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__))