mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-05 04:50:12 +03:00
Release notes
This commit is contained in:
parent
e6c0cfc279
commit
cd86aa5bc7
|
@ -19,11 +19,21 @@
|
|||
|
||||
# Django REST framework 3.6
|
||||
|
||||
The 3.6 release adds two major new features to REST framework.
|
||||
|
||||
1. Built-in interactive API documentation support.
|
||||
2. A new JavaScript client library.
|
||||
|
||||
**TODO: Insert image**
|
||||
|
||||
*Above: The interactive API documentation.*
|
||||
|
||||
---
|
||||
|
||||
## Funding
|
||||
|
||||
The 3.6 release would not have been possible without our [collaborative funding model][funding].
|
||||
The 3.6 release would not have been possible without our [backing from Mozilla](mozilla-grant.md) to the project, and our [collaborative funding model][funding].
|
||||
|
||||
If you use REST framework commercially and would like to see this work continue,
|
||||
we strongly encourage you to invest in its continued development by
|
||||
**[signing up for a paid plan][funding]**.
|
||||
|
@ -40,24 +50,134 @@ we strongly encourage you to invest in its continued development by
|
|||
|
||||
*Many thanks to all our [sponsors][sponsors], and in particular to our premium backers, [Rover](http://jobs.rover.com/), [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf), [Machinalis](https://hello.machinalis.co.uk/), [Rollbar](https://rollbar.com), and [MicroPyramid](https://micropyramid.com/django-rest-framework-development-services/).*
|
||||
|
||||
|
||||
---
|
||||
|
||||
## API documentation
|
||||
## Interactive API documentation
|
||||
|
||||
...
|
||||
REST framework's new API documentation supports a number of features:
|
||||
|
||||
## JavaScript Client
|
||||
* Live API interaction.
|
||||
* Support for various authentication schemes.
|
||||
* Code snippets for the Python, JavaScript, and Command Line clients.
|
||||
|
||||
...
|
||||
To install the API documentation, you'll need to include it in your projects URLconf:
|
||||
|
||||
from rest_framework.documentation import include_docs_urls
|
||||
|
||||
API_TITLE = 'API title'
|
||||
API_DESCRIPTION = '...'
|
||||
|
||||
urlpatterns = [
|
||||
...
|
||||
url(r'^docs/', include_docs_urls(title=API_TITLE, description=API_DESCRIPTION))
|
||||
]
|
||||
|
||||
Once installed you should see something a little like this:
|
||||
|
||||
**TODO: Image**
|
||||
|
||||
We'll likely be making further refinements to the API documentation over the
|
||||
coming weeks. Keep in mind that this is a new feature, and please do give
|
||||
us feedback if you run into any issues or limitations.
|
||||
|
||||
For more information on documenting your API endpoints see the ["Documenting your API"][api-docs] section.
|
||||
|
||||
## JavaScript client library
|
||||
|
||||
The JavaScript client library allows you to load an API schema, and then interact
|
||||
with that API at an application layer interface, rather than constructing fetch
|
||||
requests explicitly.
|
||||
|
||||
Here's a brief example that demonstrates:
|
||||
|
||||
* Loading the client library and schema.
|
||||
* Instantiating an authenticated client.
|
||||
* Making an API request using the client.
|
||||
|
||||
**index.html**
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<script src="/static/rest_framework/js/coreapi-0.1.0.js"></script>
|
||||
<script src="/docs/schema.js' %}"></script>
|
||||
<script>
|
||||
const coreapi = window.coreapi
|
||||
const schema = window.schema
|
||||
|
||||
// Instantiate a client...
|
||||
let auth = coreapi.auth.TokenAuthentication({scheme: 'JWT', token: 'xxx'})
|
||||
let client = coreapi.Client({auth: auth})
|
||||
|
||||
// Make an API request...
|
||||
client.action(schema, ['projects', 'list']).then(function(result) {
|
||||
alert(result)
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
||||
|
||||
The JavaScript client library supports various authentication schemes, and can be
|
||||
used by your project itself, or as an external client interacting with your API.
|
||||
|
||||
The client is not limited to usage with REST framework APIs, although it does
|
||||
currently only support loading CoreJSON API schemas. Support for Swagger and
|
||||
other API schemas is planned.
|
||||
|
||||
For more details see the [JavaScript client library documentation][js-docs].
|
||||
|
||||
## Authentication classes for the Python client library
|
||||
|
||||
Previous authentication support in the Python client library was limited to
|
||||
allowing users to provide explicit header values.
|
||||
|
||||
We now have better support for handling the details of authentication, with
|
||||
the introduction of the `BasicAuthentication`, `TokenAuthentication`, and
|
||||
`SessionAuthentication` schemes.
|
||||
|
||||
You can include the authentication scheme when instantiating a new client.
|
||||
|
||||
auth = coreapi.auth.TokenAuthentication(scheme='JWT', token='xxx-xxx-xxx')
|
||||
client = coreapi.Client(auth=auth)
|
||||
|
||||
For more information see the [Python client library documentation][py-docs].
|
||||
|
||||
---
|
||||
|
||||
## Deprecations
|
||||
|
||||
...
|
||||
### DjangoFilterBackend
|
||||
|
||||
The functionality of the built-in `DjangoFilterBackend` is now completely
|
||||
included by the `django-filter` package.
|
||||
|
||||
You should change your imports and REST framework filter settings as follows:
|
||||
|
||||
* `rest_framework.filters.DjangoFilterBackend` becomes `django_filters.rest_framework.DjangoFilterBackend`.
|
||||
* `rest_framework.filters.FilterSet` becomes `django_filters.rest_framework.FilterSet`.
|
||||
|
||||
The existing imports will continue to work but are now pending deprecation.
|
||||
|
||||
---
|
||||
|
||||
## What's next
|
||||
|
||||
There are likely to be a number of refinements to the API documentation and
|
||||
JavaScript client library over the coming weeks, which could include some of the following:
|
||||
|
||||
* Support for private API docs, requiring login.
|
||||
* File upload and download support in the JavaScript client & API docs.
|
||||
* Comprehensive documentation for the JavaScript client library.
|
||||
* Automatically including authentication details in the API doc code snippets.
|
||||
* Adding authentication support in the command line client.
|
||||
* Support for loading Swagger and other schemas in the JavaScript client.
|
||||
* Improved support for documenting parameter schemas and response schemas.
|
||||
* Refining the API documentation interaction modal.
|
||||
|
||||
Once work on those refinements is complete, we'll be starting feature work
|
||||
on realtime support, for the 3.7 release.
|
||||
|
||||
[sponsors]: https://fund.django-rest-framework.org/topics/funding/#our-sponsors
|
||||
[funding]: funding.md
|
||||
[api-docs]: documenting-your-api.md
|
||||
[js-docs]: api-clients.md#javascript-client-library
|
||||
[py-docs]: api-clients.md#python-client-library
|
||||
|
|
|
@ -240,9 +240,59 @@ Once we have a `Client` instance, we can fetch an API schema from the network.
|
|||
schema = client.get('https://api.example.org/')
|
||||
|
||||
The object returned from this call will be a `Document` instance, which is
|
||||
the internal representation of the interface that we are interacting with.
|
||||
a representation of the API schema.
|
||||
|
||||
Now that we have our schema `Document`, we can now start to interact with the API:
|
||||
## Authentication
|
||||
|
||||
Typically you'll also want to provide some authentication credentials when
|
||||
instantiating the client.
|
||||
|
||||
#### Token authentication
|
||||
|
||||
The `TokenAuthentication` class can be used to support REST framework's built-in
|
||||
`TokenAuthentication`, as well as OAuth and JWT schemes.
|
||||
|
||||
auth = coreapi.auth.TokenAuthentication(
|
||||
scheme='JWT'
|
||||
token='<token>'
|
||||
)
|
||||
client = coreapi.Client(auth=auth)
|
||||
|
||||
When using TokenAuthentication you'll probably need to implement a login flow
|
||||
using the CoreAPI client.
|
||||
|
||||
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
|
||||
|
||||
client = coreapi.Client()
|
||||
schema = client.get('https://api.example.org/')
|
||||
|
||||
action = ['api-token-auth', 'obtain-token']
|
||||
params = {username: "example", email: "example@example.com"}
|
||||
result = client.action(schema, action, params)
|
||||
|
||||
auth = coreapi.auth.TokenAuthentication(
|
||||
scheme='JWT',
|
||||
token=result['token']
|
||||
)
|
||||
client = coreapi.Client(auth=auth)
|
||||
|
||||
#### Basic authentication
|
||||
|
||||
The `BasicAuthentication` class can be used to support HTTP Basic Authentication.
|
||||
|
||||
auth = coreapi.auth.BasicAuthentication(
|
||||
username='<username>',
|
||||
password='<password>'
|
||||
)
|
||||
client = coreapi.Client(auth=auth)
|
||||
|
||||
## Interacting with the API
|
||||
|
||||
Now that we have a client and have fetched our schema `Document`, we can now
|
||||
start to interact with the API:
|
||||
|
||||
users = client.action(schema, ['users', 'list'])
|
||||
|
||||
|
@ -330,12 +380,23 @@ There are two separate JavaScript resources that you need to include in your HTM
|
|||
|
||||
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'))
|
||||
from rest_framework.documentation import include_docs_urls
|
||||
|
||||
urlpatterns = [
|
||||
...
|
||||
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 the CoreAPI library and the API schema.
|
||||
|
||||
/static/rest_framework/js/coreapi-0.1.0.js
|
||||
/docs/schema.js
|
||||
-->
|
||||
{% load staticfiles %}
|
||||
<script src="{% static 'rest_framework/js/coreapi.js' %}"></script>
|
||||
<script src="{% static 'rest_framework/js/coreapi-0.1.0.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.
|
||||
|
@ -345,64 +406,48 @@ The `coreapi` library, and the `schema` object will now both be available on the
|
|||
|
||||
## Instantiating a client
|
||||
|
||||
In order to interact with the API you'll need a client instance.
|
||||
|
||||
var client = coreapi.Client()
|
||||
|
||||
Header authentication
|
||||
Typically you'll also want to provide some authentication credentials when
|
||||
instantiating the client.
|
||||
|
||||
var auth = coreapi.auth.HeaderAuthentication({
|
||||
value: 'JWT <token>'
|
||||
})
|
||||
var client = coreapi.Client({auth: auth})
|
||||
#### Session authentication
|
||||
|
||||
Basic authentication
|
||||
The `SessionAuthentication` class allows session cookies to provide the user
|
||||
authentication. You'll want to provide a standard HTML login flow, to allow
|
||||
the user to login, and then instantiate a client using session 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')
|
||||
csrfCookieName: 'csrftoken',
|
||||
csrfHeaderName: 'X-CSRFToken'
|
||||
})
|
||||
let client = coreapi.Client({auth: auth})
|
||||
|
||||
## Using the client
|
||||
The authentication scheme will handle including a CSRF header in any outgoing
|
||||
requests for unsafe HTTP methods.
|
||||
|
||||
Making requests
|
||||
#### Token authentication
|
||||
|
||||
let action = ["users", "list"]
|
||||
client.action(schema, action).then(function(result) {
|
||||
// Return value is in 'result'
|
||||
The `TokenAuthentication` class can be used to support REST framework's built-in
|
||||
`TokenAuthentication`, as well as OAuth and JWT schemes.
|
||||
|
||||
let auth = coreapi.auth.TokenAuthentication({
|
||||
scheme: 'JWT'
|
||||
token: '<token>'
|
||||
})
|
||||
let client = coreapi.Client({auth: auth})
|
||||
|
||||
Including parameters
|
||||
When using TokenAuthentication you'll probably need to implement a login flow
|
||||
using the CoreAPI client.
|
||||
|
||||
let action = ["users", "create"]
|
||||
let params = {username: "example", email: "example@example.com"}
|
||||
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
|
||||
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
|
||||
// Setup some globally accessible state
|
||||
window.client = coreapi.Client()
|
||||
window.loggedIn = false
|
||||
|
||||
|
@ -411,8 +456,10 @@ For example, using the "Django REST framework JWT" package
|
|||
let params = {username: "example", email: "example@example.com"}
|
||||
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)
|
||||
let auth = window.coreapi.auth.TokenAuthentication({
|
||||
scheme: 'JWT',
|
||||
token: result['token']
|
||||
})
|
||||
window.client = coreapi.Client({auth: auth})
|
||||
window.loggedIn = true
|
||||
}).catch(function (error) {
|
||||
|
@ -420,6 +467,41 @@ For example, using the "Django REST framework JWT" package
|
|||
})
|
||||
}
|
||||
|
||||
#### Basic authentication
|
||||
|
||||
The `BasicAuthentication` class can be used to support HTTP Basic Authentication.
|
||||
|
||||
let auth = coreapi.auth.BasicAuthentication({
|
||||
username: '<username>',
|
||||
password: '<password>'
|
||||
})
|
||||
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: "example@example.com"}
|
||||
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'
|
||||
})
|
||||
|
||||
## Installation with node
|
||||
|
||||
The coreapi package is available on NPM.
|
||||
|
|
Loading…
Reference in New Issue
Block a user