Feel Good.

31 августа 2010

Enum поле в XML API

Проектируя публичное API очень важно понимать, что Ваше API будут использовать другие разработчики различного уровня, которые будут вынуждены разбираться в нем с нуля. Именно поэтому важную роль здесь играет простота и понятность созданного Вами API. Интуитивно-понятное API намного проще осваивать, и тем более использовать. Любое API подразумевает обмен сообщениями между "клиентом" и "сервером", и зачастую такие сообщения удобно записывать в виде XML. Стандартная ситуация, Вы формируете некий XML и посылаете его на сервер, сервер разбирает его и отвечает Вам другим XML (XML API). К примеру, это может быть запрос аутентификации:

<request>

    <auth>

        <login>ilya</login>

        <password>*****</password>

    </auth>

</request>


и соответственно ответ на запрос со стороны сервера будет выглядеть следующим образом:

<response>

    <result>42</result>

 

    <!-- Остальные поля ответа... -->

</response>



С подобным в своей практике мне приходилось сталкиваться ни раз, поэтому решил написать об этом пост. На первый взгляд в ответе с сервера нет ничего подозрительного, но это только кажется. К примеру мы никогда не узнаем что обозначает код возврата 42, не имея под рукой документации к API, google. Более того, имея под рукой документацию, нам каждый раз придется нырять в нее, уточняя каждый полученный статус, либо придется держать его в уме. Еще хуже, это унаследовать число 42 в следующей версии API, со ссылкой на предыдущую.
Но все не так уж и плохо, данную проблему можно устранить, если записывать все коды, статусы, enum-поля и подобное в виде строк:

<response>

    <result>LoginIncorrect</result>

 

    <!-- Остальные поля ответа... -->

</response>


Код "LoginIncorrect" более информативен нежели код "42". Даже не имея под рукой документации можно понять, что аутентификация прошла неуспешно, потому что пользователь с логином "ilya" не зарегистрирован в системе. Можно возразить, что передавать "LoginIncorrect" вместо "42" расточительно, но это только кажется. В противном случае переходите на бинарный протокол обмена данными.

Мой совет: всегда при проектировании внешнего XML API записываете все коды, статусы, enum-поля и подобное в виде строковых констант.

Progg it

8 комментариев:

  1. Что за привычка размещать удобные данные не в атрибутах, а раздувать трафик элементами....

    Павбывав бы ;)

    ОтветитьУдалить
  2. Даже если так:
    [response result="42"][/response]
    против
    [response result="LoginIncorrect"][/response]
    Здесь все дело в идеи не экономить в ущерб"понятности" API.

    ОтветитьУдалить
  3. А сконвертировать на стороне клиента на судьба? Ведь у Enum есть методы преобразования в значения. Если код не из enum, то и это можно обработать.

    ОтветитьУдалить
  4. @Александр
    Это дело вкуса, но на мой взгляд лучше не привязываться к числовым кодам в XML API.
    Чем числовое поле, в данном случае, выгоднее строки? Вот строка выгоднее тем, что более информативна.

    ОтветитьУдалить
  5. Как уже сказали выше, на клиенте всегда можно определить Enum, в котором будут прописаны нужные значения - при десериализации они автоматически будут конвертироваться в нужный тип. Впрочем как и строковые значения. А для написания своего энума все равно придется смотреть в документацию.

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

    ОтветитьУдалить
  6. Про атрибуты наверно имелось ввиду вот так
    [response result="42" /]

    А для наглядности конечно лучше сделать пояснение (мое мнение)

    [response result="42" ] Пояснение тут [/response]

    ОтветитьУдалить
  7. Возможно, это и есть компромиссное решение: одновременно с числовым кодом возвращать еще и локализованное пояснение. Хотя практическое использование в приложении локализованного пояснения дело сомнительное.

    ОтветитьУдалить
  8. Поддерживаю автора поста на 100%.

    Если уж используем XML, значит нам трафик не критичен. В этом случае нужно всегда возвращать результат как строку, а не как статус-код.

    Если экономим на трафике, значит только в бинарном виде.

    ОтветитьУдалить