Skip to content

Commit

Permalink
Client library & API documentation docs (encode#4939)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomchristie authored Mar 6, 2017
1 parent 68d2020 commit 0b708f0
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 6 deletions.
122 changes: 121 additions & 1 deletion docs/topics/api-clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ other protocols can also be supported.

#### Configuring transports

The behaviour of the network layer can be customized by configuring the
The behavior of the network layer can be customized by configuring the
transports that the client is instantiated with.

import requests
Expand All @@ -318,6 +318,126 @@ More complex customizations can also be achieved, for example modifying the
underlying `requests.Session` instance to [attach transport adaptors][transport-adaptors]
that modify the outgoing requests.

---

# JavaScript Client Library

The JavaScript client library allows you to interact with your API either from a browser, or using node.

## Installing the JavaScript client

There are two separate JavaScript resources that you need to include in your HTML pages in order to use the JavaScript client library. These are a static `coreapi.js` file, which contains the code for the dynamic client library, and a templated `schema.js` resource, which exposes your API schema.

First, install the API documentation views. These will include the schema resource that'll allow you to load the schema directly from an HTML page, without having to make an asynchronous AJAX call.

url(r'^docs/', include_docs_urls(title='My API service'))

Once the API documentation URLs are installed, you'll be able to include both the required JavaScript resources. Note that the ordering of these two lines is important, as the schema loading requires CoreAPI to already be installed.

{% load staticfiles %}
<script src="{% static 'rest_framework/js/coreapi.js' %}"></script>
<script src="{% url 'api-docs:schema-js' %}"></script>

The `coreapi` library, and the `schema` object will now both be available on the `window` instance.

const coreapi = window.coreapi
const schema = window.schema

## Instantiating a client

var client = coreapi.Client()

Header authentication

var auth = coreapi.auth.HeaderAuthentication({
value: 'JWT <token>'
})
var client = coreapi.Client({auth: auth})

Basic authentication

var auth = coreapi.auth.BasicAuthentication({
userName: '<username>',
password: '<password>'
})
var client = coreapi.Client({auth: auth})

Session authentication

// https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
let auth = coreapi.auth.SessionAuthentication({
csrfHeader: 'X-CSRFToken',
csrfToken: getCookie('csrftoken')
})
let client = coreapi.Client({auth: auth})

## Using the client

Making requests

let action = ["users", "list"]
client.action(schema, action).then(function(result) {
// Return value is in 'result'
})

Including parameters

let action = ["users", "create"]
let params = {username: "example", email: "[email protected]"}
client.action(schema, action, params).then(function(result) {
// Return value is in 'result'
})

Handling errors

client.action(schema, action, params).then(function(result) {
// Return value is in 'result'
}).catch(function (error) {
// Error value is in 'error'
})

If you're using session authentication, and handling login requests using regular HTML forms then you probably won't need an authentication flow for the client. However, if you're using one of the other types of authentication,

A suggested pattern for this would be to initially make an unauthenticated client request to an "obtain token" endpoint

For example, using the "Django REST framework JWT" package

// Globally accessible state
window.client = coreapi.Client()
window.loggedIn = false

function loginUser(username, password) {
let action = ["api-token-auth", "obtain-token"]
let params = {username: "example", email: "[email protected]"}
client.action(schema, action, params).then(function(result) {
// On success, instantiate an authenticated client.
let authConfig = {value: 'JWT ' + result['token']}
let auth = window.coreapi.auth.HeaderAuthentication(authConfig)
window.client = coreapi.Client({auth: auth})
window.loggedIn = true
}).catch(function (error) {
// Handle error case where eg. user provides incorrect credentials.
})
}

## Installation with node

The coreapi package is available on NPM.

$ npm install coreapi
$ node
const coreapi = require('coreapi')

You'll either want to include the API schema in your codebase directly, by copying it from the `schema.js` resource, or else load the schema asynchronously. For example:

let client = new coreapi.Client()
let schema = null
client.get("https://api.example.org/").then(function(data) {
// Load a CoreJSON API schema.
schema = data
console.log('schema loaded')
})

[heroku-api]: https://devcenter.heroku.com/categories/platform-api
[heroku-example]: http://www.coreapi.org/tools-and-resources/example-services/#heroku-json-hyper-schema
[core-api]: http://www.coreapi.org/
Expand Down
65 changes: 60 additions & 5 deletions docs/topics/documenting-your-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,73 @@
>
> &mdash; Roy Fielding, [REST APIs must be hypertext driven][cite]
There are a variety of approaches to API documentation. This document introduces a few of the various tools and options you might choose from. The approaches should not be considered exclusive - you may want to provide more than one documentation style for you API, such as a self describing API that also includes static documentation of the various API endpoints.
REST framework provides built-in support for API documentation. There are also a number of great third-party documentation tools available.

##
## Built-in API documentation

... TODO ...
The built-in API documentation includes:

## Third party packages
* Documentation of API endpoints.
* Automatically generated code samples for each of the available API client libraries.
* Support for API interaction.

There are a number of mature third-party packages for providing API documentation.
### Installation

To install the API documentation, you'll need to include it in your projects URLconf:

from rest_framework.documentation import include_docs_urls

urlpatterns = [
...
url(r'^docs/', include_docs_urls(title='My API title'))
]

This will include two different views:

* `/docs/` - The documentation page itself.
* `/docs/schema.js` - A JavaScript resource that exposes the API schema.

### Documenting your views

You can document your views by including docstrings that describe each of the available actions.
For example:

class UserList(generics.ListAPIView):
"""
Return a list of all the existing users.
""""

If a view supports multiple methods, you should split your documentation using `method:` style delimiters.

class UserList(generics.ListCreateAPIView):
"""
get:
Return a list of all the existing users.

post:
Create a new user instance.
"""

When using viewsets, you should use the relevant action names as delimiters.

class UserViewSet(viewsets.ModelViewSet):
"""
retrieve:
Return the given user.

list:
Return a list of all the existing users.

create:
Create a new user instance.
"""

---

## Third party packages

There are a number of mature third-party packages for providing API documentation.

#### DRF Docs

[DRF Docs][drfdocs-repo] allows you to document Web APIs made with Django REST Framework and it is authored by Emmanouil Konstantinidis. It's made to work out of the box and its setup should not take more than a couple of minutes. Complete documentation can be found on the [website][drfdocs-website] while there is also a [demo][drfdocs-demo] available for people to see what it looks like. **Live API Endpoints** allow you to utilize the endpoints from within the documentation in a neat way.
Expand Down

0 comments on commit 0b708f0

Please sign in to comment.