Новый REST API Яндекс.Диска и Полигон. А также зачем Диску ещё один API и как мы его делали

в 9:16, , рубрики: api, Блог компании Яндекс, облачные хранилища, Яндекс API, Яндекс.Диск, метки: , ,

Многие знают, что у Диска уже достаточно давно есть API на WebDAV. Он достаточно узко заточен под работу с файловой структурой, а у его реализации на разных платформах часто бывают некритичные, но не очень приятные недостатки. Поэтому в дополнение к WebDAV мы запускаем REST API, который позволит разработчикам делать всё то же и немного больше.

Например, при использовании нового API все приложения, которым просто нужно хранить свои файлы в Диске, смогут получать доступ только к своей папке, лежащей в Диске пользователя в папке «Приложения». В WebDAV API сервису для этого придётся получать у пользователя разрешение на запись/чтение всего Диска, а не только конкретной папки.

Новый REST API Яндекс.Диска и Полигон. А также зачем Диску ещё один API и как мы его делали

В этом посте я хочу рассказывать не о структуре или об операциях, которые умеет выполнять наш API — там всё довольно очевидно — а сразу перейду к интересным вещам: что такое Hypermedia и Machine-readable and Self-describing API, и как мы все это реализовали.

Hypermedia API

Мы снабдили наш API гиперссылками, которые связывают его ресурсы между собой. Они позволяют превратить работу клиента из дёрганья захардкоденных URL в перемещение по ссылкам, которые предоставляет API в теле возвращаемых объектов. Мы взяли за основу стандартHAL, как один из наиболее простых и зрелых стандартов в этой области. В настоящее время HAL имеет драфт RFC-стандарта и его уже можно встретить в API некоторых крупных компаний.

Благодаря поддержке HAL клиент понимает, что можно делать с каждым объектом, знает готовый или шаблонизированный в соответствии с RFC 6570 URL и HTTP-метод действия. В свою очередь, разработчики клиентских приложений могут писать меньше кода, тратя на это меньше времени, а этот код становится проще и легче для восприятия. Например, код, выполняющий базовые операции с папками в Диске, не использующий гиперссылки, будет выглядеть примерно так:

Скрытый текст

# -*- coding: utf-8 -*-
import urllib
import httplib
import json
import uritemplate

headers = {'Authorization': '<OAuth токен>', 'Accept': 'application/hal+json'}
connection = httplib.HTTPSConnection('cloud-api.yandex.net')
resource_url = '/v1/disk/resources?path={path}'

def request(method, url, params=None):
    url = uritemplate.expand(url, params or {})
    connection.request(method, url, headers=headers)
    resp = connection.getresponse()
    content = resp.read()
    obj = json.loads(content) if content else None
    status = resp.status
    if status == 201:
        # получаем созданный объект
        status, obj = request(obj['method'], obj['href'])
    return status, obj

def do(resource, action, params=None):
    link = resource['_links'][action]
    _, obj = request(link['method'], link['href'], params)
    return obj

if __name__ == '__main__':
    # создаём папку
    _, folder = request('PUT', uritemplate.expand(resource_url, {'path': '/foo'}))

    # перемещаем папку и получаем перемещённую
    folder = do(folder, 'move', {'path': '/bar'})

    # копируем папку и получаем новую папку
    folder_copy = do(folder, 'copy', {'path': '/foobar'})

    # удаляем папки
    do(folder, 'delete')
    do(folder_copy, 'delete')

При использовании гиперссылок пропадает необходимость вручную собирать URL и беспокоиться о параметрах запроса и без того известных объекту, над которым выполняется операция:

Скрытый текст

# -*- coding: utf-8 -*-
import urllib
import httplib
import json
import uritemplate

headers = {'Authorization': '<OAuth токен>'}
connection = httplib.HTTPSConnection('cloud-api.yandex.net')
resource_url = '/v1/disk/resources'

def request(method, url, query=None):
    if query:
        qs = urllib.urlencode(query)
        url = '%s?%s' % (url, qs)
    connection.request(method, url, headers=headers)
    resp = connection.getresponse()
    content = resp.read()
    obj = json.loads(content) if content else None
    status = resp.status
    if status == 201:
        # получаем созданный объект
        obj = request(obj['method'], obj['href'])
    return obj

if __name__ == '__main__':
    # создаём папку
    path = '/foo'
    folder = request('PUT', resource_url, {'path': path})

    # перемещаем папку и получаем перемещённую
    new_path = '/bar'
    folder = request('POST', '%s/move' % resource_url, {'path': new_path, 'from': path})

    # копируем папку и получаем новую папку
    copy_path = '/foobar'
    folder_copy = request('POST', '%s/copy' % resource_url, {'path': copy_path, 'from': new_path})

    # удаляем папки
    request('DELETE', resource_url, {'path': new_path})
    request('DELETE', resource_url, {'path': copy_path})

Machine-readable & Self-describing API

Кроме гипермедиа мы решили сделать наш API самоописываемым и машиночитаемым. В процессе подготовки мы изучили различные стандарты описания REST API, такие как RAML, WADL, JSON Schema+JSON HyperSchema, IO Docs, Apiary Blueprints, однако окончательный выбор пал на Swagger. Одно из основных преимуществSwagger заключается в том, что он развивается как стандарт (API Яндекс.Диска поддерживает версию спецификации 1.2, но сейчас уже ведётся разработка версии стандарта 2.0). Он описывает REST API с помощью JSON, достаточно прост для понимания и имеет неплохую экосистему инструментов для работы с описаниями API.

Swagger-документация охватывает все доступные в API ресурсы и методы их вызова. Для каждого метода ресурса есть описание принимаемых им параметров и структуры возвращаемых объектов.

Это описание можно использовать, как в качестве отправной точки для универсальных Swagger-клиентов, так и для автогенерации части кода нативных SDK для различных языков.

Полигон

Благодаря наличию Swagger-документации API мы запустили проект Полигонкоторый даёт разработчикам возможность, не написав ни строчки кода, отправлять боевые запросы в API. Кроме того, Полигон может служить примером универсального клиента для любого API, поддерживающего Swagger-описание. Наш разработчик Рома Акинфеев подготовил скринкаст, в котором рассказал немного о возможностях Полигона.

Больше приложений хороших и разных!

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

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

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

Автор: vladimirrusinov

Источник

Поделиться

* - обязательные к заполнению поля