Статьи

Универсальность API

Клиент никогда не должен решать, как должен реагировать сервер.

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

Позвольте мне объяснить это немного.

Недавно у нас был проект с одной из телекоммуникационных компаний, и мы должны иметь возможность открыть API для общения с SMS-шлюзом, а также с  IVR . Мы определили набор правил, которые никогда не должны изменяться, пока не наступит конец света. Одним из API является ресурс, который может хранить данные в базе данных на основе SMS пользователя.

Допустим, пользователь вводит их в свой телефон и отправляет в виде текстового сообщения на наш сервер:

РЕГИСТРАЦИЯ Джон Доу # 12345678 # 10-04-2002 # Джакарта

и пользователь, Джон, получит много информации с сервера, как это:

Добро пожаловать, Джон Доу. Приятно встретить вас здесь, и мы рады приветствовать вас на нашем новом сервисе. Позади вас 102 452 человека, ожидающих доступа к этой услуге, и они не могут дождаться, чтобы присоединиться к новой эре общения. Еще раз поздравляю вас с тем, что вы присоединились сегодня, и вот ваше имя пользователя и пароль. Имя пользователя: johndoe. Пароль: johndoe123.

Бэкэнд будет выглядеть примерно так:

Джон Доу отправит текстовое сообщение на короткий номер 1234, и телефон отправит его через  MSC  и  SMSC . SMSC пересылает пакет на SMS-шлюз, а SMS-шлюз передает информацию на сервер. Ответ сервера будет принят шлюзом SMS и перенаправлен в SMSC. SMSC для MSC и, наконец, пользователь получает ответ от MSC. (Fiuh, какой запутанный мир, в котором мы жили).

Итак, почему все это связано с универсальностью API?

Далее мы обсудим, как сделать длинный ответ подходящим для телефона пользователя, не нарушив ни единого слова. Как мы уже знаем, размер SMS-сообщения ограничен 160 символами, и у нас ответ превышает это ограничение, оно будет разбито на два или более текстовых сообщения. Все хорошо. Нет проблем с этим.

Проблема в том, что мы не хотим разбивать даже одно слово на две части, которые вообще не имеют смысла. Возьмем в качестве примера:  добро пожаловать  стать  вэй приходят , коммуникации  становятся  COMMUN ication , и так далее. Это не хорошо.

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

Но как?

Одна из нашей команды предполагает, что ответ сервера будет примерно таким:

{'status':'OK','code':'200','data':{'response':'register_ok','response_txt':'Welcome, John Doe. It\'s nice to meet you
                       here and we welcome you to our brand new service.
                       There are 102,452 | people behind you waiting to access
                        this service and can\'t wait to join the new era
                        of communication. Once again, congratulations
                        on your joining | today and here is your username
                        along with a password. Username: johndoe.
                        Password: johndoe123.
                }
}

(Если вы заметили, что я помещаю трубу ‘|’, да, вы правы. Это разделитель для каждых 160 символов. Хотя я не поместил его точно на 160-й символ. Это просто для иллюстрации.)

Это предложение звучит очень хорошо и решает проблему. Но имейте в виду, что эта проблема также нарушает  правило APIуниверсальность  (или, другими словами,  универсальность ) и потенциально создает проблемы.

Так в чем проблема?

Таким образом, благодаря новому API, шлюз SMS может разбить длинный ответ на части, каждая часть имеет не более 160 символов. Все счастливы. SMS-шлюз счастлив. Пользователь также счастлив (или, возможно, не волнует вообще). Но как насчет другого стороннего приложения (такого как Android или iOS-клиент), которое решило использовать наш API?

Да, они также должны разделить ответ. Или правильный способ сделать это — удалить разделитель ‘|’ Чар из ответа. Но это не правильный путь. И вдруг все сторонние клиенты задают вопросы и жалуются на наш API, почему в мире мы всегда ставим трубу в середине нашего ответа?

Решение

Клиент никогда не должен решать, как должен реагировать сервер. Мы откатили API до прежнего состояния — длинный ответ без отвратительного канала — и предлагаем эту простую функцию, написанную на Python, для решения проблемы SMS-шлюза:

def split_to_sms(txt):
    results =[]
    txt_temp = txt

    while len(txt_temp)>160:
        cut_pos =string.rfind(txt_temp,' ',0,160)
        results.append(txt_temp[0: cut_pos])
        txt_temp = txt_temp[cut_pos +1:]if len(txt_temp)>0:
        results.append(txt_temp)return results

Мы поместили код в клиент (SMS Gateway), и теперь все действительно довольны (хотя пользователю все равно, ответ почти такой же, как и раньше).

Проблема решена без ущерба для принципа разработки API.