Клиенты API

Клиент API обрабатывает основные детали того, как выполняются сетевые запросы и как декодируются ответы. Они предоставляют разработчику интерфейс приложения для работы, а не работают непосредственно с сетевым интерфейсом.

Клиенты API, описанные здесь, не ограничиваются API, построенными с помощью фреймворка Django REST.

Их можно использовать с любым API, который предоставляет поддерживаемый формат схемы.

Например, the Heroku platform API раскрывает схему в формате JSON Hyperschema. В результате клиент командной строки Core API и клиентская библиотека Python могут быть used to interact with the Heroku API.

Основной API на стороне клиента

Core API - это спецификация документа, которая может быть использована для описания API. Она может использоваться либо на стороне сервера, как это делается в :doc:`schema generation <../api-guide/schemas>`** фреймворке REST, либо на стороне клиента, как описано здесь.

При использовании на стороне клиента, Core API позволяет создавать динамически управляемые клиентские библиотеки, которые могут взаимодействовать с любым API, раскрывающим поддерживаемую схему или формат гипермедиа.

Использование динамически управляемого клиента имеет ряд преимуществ перед взаимодействием с API путем создания HTTP-запросов напрямую.

Более содержательное взаимодействие

Взаимодействие API представлено в более осмысленном виде. Вы работаете на уровне интерфейса приложения, а не на уровне сетевого интерфейса.

Устойчивость и эволюционность

Клиент определяет, какие конечные точки доступны, какие параметры существуют для каждой конкретной конечной точки, и как формируются HTTP-запросы.

Это также обеспечивает определенную степень эволюционности API. URL-адреса могут быть изменены без нарушения работы существующих клиентов, или более эффективные кодировки могут быть использованы по проводам, с прозрачным обновлением клиентов.

Самоописывающиеся API

Динамически управляемый клиент способен представить конечному пользователю документацию по API. Эта документация позволяет пользователю обнаружить доступные конечные точки и параметры, а также лучше понять API, с которым он работает.

Поскольку эта документация определяется схемой API, она всегда будет полностью соответствовать последней развернутой версии сервиса.


Клиент командной строки

Клиент командной строки позволяет вам проверять и взаимодействовать с любым API, который раскрывает поддерживаемый формат схемы.

Начало работы

Чтобы установить клиент командной строки Core API, используйте pip.

Обратите внимание, что клиент командной строки является отдельным пакетом по отношению к клиентской библиотеке python. Обязательно установите coreapi-cli.

$ pip install coreapi-cli

Чтобы начать осмотр и взаимодействие с API, схема должна быть сначала загружена из сети.

$ coreapi get http://api.example.org/
<Pastebin API "http://127.0.0.1:8000/">
snippets: {
    create(code, [title], [linenos], [language], [style])
    destroy(pk)
    highlight(pk)
    list([page])
    partial_update(pk, [title], [code], [linenos], [language], [style])
    retrieve(pk)
    update(pk, code, [title], [linenos], [language], [style])
}
users: {
    list([page])
    retrieve(pk)
}

Затем будет загружена схема, в результате чего отобразится Document. Эта Document включает все доступные взаимодействия, которые могут быть выполнены с API.

Чтобы взаимодействовать с API, используйте команду action. Эта команда требует список ключей, которые используются для индексации в ссылке.

$ coreapi action users list
[
    {
        "url": "http://127.0.0.1:8000/users/2/",
        "id": 2,
        "username": "aziz",
        "snippets": []
    },
    ...
]

Чтобы проверить базовый HTTP-запрос и ответ, используйте флаг --debug.

$ coreapi action users list --debug
> GET /users/ HTTP/1.1
> Accept: application/vnd.coreapi+json, */*
> Authorization: Basic bWF4Om1heA==
> Host: 127.0.0.1
> User-Agent: coreapi
< 200 OK
< Allow: GET, HEAD, OPTIONS
< Content-Type: application/json
< Date: Thu, 30 Jun 2016 10:51:46 GMT
< Server: WSGIServer/0.1 Python/2.7.10
< Vary: Accept, Cookie
<
< [{"url":"http://127.0.0.1/users/2/","id":2,"username":"aziz","snippets":[]},{"url":"http://127.0.0.1/users/3/","id":3,"username":"amy","snippets":["http://127.0.0.1/snippets/3/"]},{"url":"http://127.0.0.1/users/4/","id":4,"username":"max","snippets":["http://127.0.0.1/snippets/4/","http://127.0.0.1/snippets/5/","http://127.0.0.1/snippets/6/","http://127.0.0.1/snippets/7/"]},{"url":"http://127.0.0.1/users/5/","id":5,"username":"jose","snippets":[]},{"url":"http://127.0.0.1/users/6/","id":6,"username":"admin","snippets":["http://127.0.0.1/snippets/1/","http://127.0.0.1/snippets/2/"]}]

[
    ...
]

Некоторые действия могут включать необязательные или требуемые параметры.

$ coreapi action users create --param username=example

При использовании --param , тип входа будет определен автоматически.

Если вы хотите более четко определить тип параметра, то используйте --data для любых нулевых, числовых, булевых, списковых или объектных входов, и используйте --string для строковых входов.

$ coreapi action users edit --string username=tomchristie --data is_admin=true

Аутентификация и заголовки

Команда credentials используется для управления заголовком запроса Authentication:. Любые добавленные учетные данные всегда привязаны к определенному домену, чтобы исключить утечку учетных данных в различных API.

Формат добавления новой учетной записи следующий:

$ coreapi credentials add <domain> <credentials string>

Например:

$ coreapi credentials add api.example.org "Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b"

Дополнительный флаг --auth также позволяет вам добавлять определенные типы аутентификации, обрабатывая кодировку за вас. В настоящее время в качестве опции здесь поддерживается только "basic". Например:

$ coreapi credentials add api.example.org tomchristie:foobar --auth basic

Вы также можете добавить определенные заголовки запроса, используя команду headers:

$ coreapi headers add api.example.org x-api-version 2

Для получения дополнительной информации и списка доступных подкоманд используйте coreapi credentials --help или coreapi headers --help.

Кодеки

По умолчанию клиент командной строки включает только поддержку чтения схем Core JSON, однако он включает систему плагинов для установки дополнительных кодеков.

$ pip install openapi-codec jsonhyperschema-codec hal-codec
$ coreapi codecs show
Codecs
corejson        application/vnd.coreapi+json encoding, decoding
hal             application/hal+json         encoding, decoding
openapi         application/openapi+json     encoding, decoding
jsonhyperschema application/schema+json      decoding
json            application/json             data
text            text/*                       data

Утилиты

Клиент командной строки включает функциональность для создания закладок для URL API под запоминающимся именем. Например, вы можете добавить закладку для существующего API следующим образом…

$ coreapi bookmarks add accountmanagement

Также имеется функциональность для навигации вперед или назад по истории обращений к URL-адресам API.

$ coreapi history show
$ coreapi history back

Для получения дополнительной информации и списка доступных подкоманд используйте coreapi bookmarks --help или coreapi history --help.

Другие команды

Для отображения текущего Document :

$ coreapi show

Чтобы перезагрузить текущий Document из сети:

$ coreapi reload

Чтобы загрузить файл схемы с диска:

$ coreapi load my-api-schema.json --format corejson

Вывод текущего документа на консоль в заданном формате:

$ coreapi dump --format openapi

Чтобы удалить текущий документ вместе со всей сохраненной историей, учетными данными, заголовками и закладками:

$ coreapi clear

Клиентская библиотека Python

Пакет coreapi Python позволяет вам программно взаимодействовать с любым API, который раскрывает поддерживаемый формат схемы.

Начало работы

Перед началом работы вам необходимо установить пакет coreapi с помощью pip.

$ pip install coreapi

Для того чтобы начать работу с API, нам сначала нужен экземпляр Client. Клиент хранит все конфигурации, касающиеся того, какие кодеки и транспорты поддерживаются при взаимодействии с API, что позволяет вам обеспечить более продвинутые типы поведения.

import coreapi
client = coreapi.Client()

Как только у нас есть экземпляр Client, мы можем получить схему API из сети.

schema = client.get('https://api.example.org/')

Объект, возвращаемый этим вызовом, будет экземпляром Document, который является представлением схемы API.

Аутентификация

Как правило, при инстанцировании клиента вы также захотите предоставить некоторые учетные данные для аутентификации.

Токен-аутентификация

Класс TokenAuthentication может быть использован для поддержки встроенных TokenAuthentication, а также схем OAuth и JWT.

auth = coreapi.auth.TokenAuthentication(
    scheme='JWT',
    token='<token>'
)
client = coreapi.Client(auth=auth)

При использовании TokenAuthentication вам, вероятно, потребуется реализовать поток входа в систему с помощью клиента CoreAPI.

Предлагаемая схема для этого может заключаться в первоначальном запросе неаутентифицированного клиента к конечной точке «получения токена»

Например, используя пакет «Django REST framework JWT»

client = coreapi.Client()
schema = client.get('https://api.example.org/')

action = ['api-token-auth', 'create']
params = {"username": "example", "password": "secret"}
result = client.action(schema, action, params)

auth = coreapi.auth.TokenAuthentication(
    scheme='JWT',
    token=result['token']
)
client = coreapi.Client(auth=auth)

Базовая аутентификация

Класс BasicAuthentication может быть использован для поддержки базовой аутентификации HTTP.

auth = coreapi.auth.BasicAuthentication(
    username='<username>',
    password='<password>'
)
client = coreapi.Client(auth=auth)

Взаимодействие с API

Теперь, когда у нас есть клиент и мы получили нашу схему Document , мы можем начать взаимодействовать с API:

users = client.action(schema, ['users', 'list'])

Некоторые конечные точки могут включать именованные параметры, которые могут быть как необязательными, так и обязательными:

new_user = client.action(schema, ['users', 'create'], params={"username": "max"})

Кодеки

Кодеки отвечают за кодирование или декодирование документов.

Процесс декодирования используется клиентом, чтобы взять байтовую строку определения схемы API и вернуть Core API Document, который представляет этот интерфейс.

Кодек должен быть связан с определенным типом носителя, например 'application/coreapi+json'.

Этот медиатип используется сервером в заголовке ответа Content-Type, чтобы указать, какой тип данных возвращается в ответе.

Настройка кодеков

Доступные кодеки могут быть настроены при инстанцировании клиента. Здесь используется ключевое слово decoders , потому что в контексте клиента кодеки используются только для декодирования ответов.

В следующем примере мы настроим клиента на прием только ответов Core JSON и JSON. Это позволит нам получать и декодировать схему Core JSON, а затем получать ответы JSON, сделанные с помощью API.

from coreapi import codecs, Client

decoders = [codecs.CoreJSONCodec(), codecs.JSONCodec()]
client = Client(decoders=decoders)

Загрузка и сохранение схем

Вы можете использовать кодек напрямую, чтобы загрузить существующее определение схемы и вернуть результирующее Document.

input_file = open('my-api-schema.json', 'rb')
schema_definition = input_file.read()
codec = codecs.CoreJSONCodec()
schema = codec.load(schema_definition)

Вы также можете использовать кодек непосредственно для генерации определения схемы, заданного экземпляром Document:

schema_definition = codec.dump(schema)
output_file = open('my-api-schema.json', 'rb')
output_file.write(schema_definition)

Перевозки

Транспорты отвечают за выполнение сетевых запросов. Набор транспортов, установленных у клиента, определяет, какие сетевые протоколы он может поддерживать.

В настоящее время библиотека coreapi включает только транспорт HTTP/HTTPS, но могут поддерживаться и другие протоколы.

Конфигурирование транспортов

Поведение сетевого уровня может быть настроено путем конфигурирования транспортов, с которыми инстанцируется клиент.

import requests
from coreapi import transports, Client

credentials = {'api.example.org': 'Token 3bd44a009d16ff'}
transports = transports.HTTPTransport(credentials=credentials)
client = Client(transports=transports)

Возможны и более сложные настройки, например, модификация базового экземпляра requests.Session в attach transport adaptors, которые изменяют исходящие запросы.


Клиентская библиотека JavaScript

Клиентская библиотека JavaScript позволяет вам взаимодействовать с API либо через браузер, либо с помощью node.

Установка клиента JavaScript

Существует два отдельных ресурса JavaScript, которые необходимо включить в ваши HTML-страницы, чтобы использовать клиентскую библиотеку JavaScript. Это статический файл coreapi.js, который содержит код для динамической клиентской библиотеки, и шаблонный ресурс schema.js, который раскрывает схему вашего API.

Сначала установите представления документации API. Они будут включать ресурс схемы, который позволит вам загружать схему непосредственно с HTML-страницы, без необходимости выполнять асинхронный вызов AJAX.

from rest_framework.documentation import include_docs_urls

urlpatterns = [
    ...
    path('docs/', include_docs_urls(title='My API service'), name='api-docs'),
]

Как только URL-адреса документации API будут установлены, вы сможете включить оба необходимых ресурса JavaScript. Обратите внимание, что порядок этих двух строк важен, поскольку для загрузки схемы требуется, чтобы CoreAPI уже был установлен.

<!--
    Load the CoreAPI library and the API schema.

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

Теперь и библиотека coreapi, и объект schema будут доступны на экземпляре window.

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

Установка клиента

Для взаимодействия с API вам понадобится экземпляр клиента.

var client = new coreapi.Client();

Как правило, при инстанцировании клиента вы также захотите предоставить некоторые учетные данные для аутентификации.

Аутентификация сеанса

Класс SessionAuthentication позволяет сеансовым файлам cookie обеспечивать аутентификацию пользователя. Вы захотите предоставить стандартный поток входа в HTML, чтобы позволить пользователю войти в систему, а затем инстанцировать клиента, используя аутентификацию сеанса:

let auth = new coreapi.auth.SessionAuthentication({
    csrfCookieName: 'csrftoken',
    csrfHeaderName: 'X-CSRFToken',
});
let client = new coreapi.Client({auth: auth});

Схема аутентификации будет обрабатывать включение заголовка CSRF в любые исходящие запросы для небезопасных методов HTTP.

Токен-аутентификация

Класс TokenAuthentication может быть использован для поддержки встроенных TokenAuthentication, а также схем OAuth и JWT.

let auth = new coreapi.auth.TokenAuthentication({
    scheme: 'JWT',
    token: '<token>',
});
let client = new coreapi.Client({auth: auth});

При использовании TokenAuthentication вам, вероятно, потребуется реализовать поток входа в систему с помощью клиента CoreAPI.

Предлагаемая схема для этого может заключаться в первоначальном запросе неаутентифицированного клиента к конечной точке «получения токена»

Например, используя пакет «Django REST framework JWT»

// Setup some globally accessible state
window.client = new coreapi.Client();
window.loggedIn = false;

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

Базовая аутентификация

Класс BasicAuthentication может быть использован для поддержки базовой аутентификации HTTP.

let auth = new coreapi.auth.BasicAuthentication({
    username: '<username>',
    password: '<password>',
})
let client = new coreapi.Client({auth: auth});

Использование клиента

Выполнение запросов:

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

Включая параметры:

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'
})

Обработка ошибок:

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

Установка с помощью узла

Пакет coreapi доступен на NPM.

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

Вы захотите либо включить схему API в свою кодовую базу напрямую, скопировав ее из ресурса schema.js, либо загрузить схему асинхронно. Например:

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');
})
Вернуться на верх