Разработка мобильного ПО: проблемы интеграции



    Удобные и простые решения проблем при интеграции с серверными мощностями — что делать, если возникает задача сделать два продукта, которые бы идеально стыковались, предоставляли бы друг другу консистентные данные и сами по себе работали без сбоев.

    С подробностями Егор Тафланиди, Redmadrobot.

    Если вы не создаёте самодостаточный продукт (а таких на мобильных платформах в действительности совсем мало), вы создаёте так называемое «бизнес»-приложение, за спиной которого обычно стоит сервер, предоставляющий актуальные данные и решающий некоторые трудоёмкие задачи.

    Связка сервер/клиент настолько прочно вросла в среду мобильной разработки, что современный «умный телефон» без подключения к интернету может просто превратиться в кирпич. Некоторые библиотеки и framework'и (типа RhoMobile/RhoConnect) в своей сути строятся вокруг этой самой сервер/клиент интеграции, оставляя её глубоко «под капотом».

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

    • Разработку можно доверить одному человеку (или же тесно сотрудничающей команде, сидящей в одной комнате – это одно и то же). Он сам состыкует все необходимые узлы и максимально эффективно решит все возникающие проблемы интеграции.
    • Вы можете отдать реализацию сервера своим партнёрам, занимающимся разработкой серверного ПО.
    • У заказчика может быть своя команда серверных разработчиков – так часто бывает в случаях сотрудничества с банками.

    Какой бы вариант вы не выбрали, к сожалению, зачастую даже чётко прописанная спецификация протокола взаимодействия сервер/клиент не может обеспечить корректную интеграцию. И перед вами возникнет простая, очевидная проблема: протоколы клиента и сервера не совпадают.

    С точки зрения разработки клиента это приводит к тому, что мобильное приложение получает некорректные данные. Или же не получает их вовсе.
    Если архитектурный дизайн недостаточно «пуленепробиваем», и времени на разработку было выделено мало – приложение будет «падать», отображать белиберду и вообще вести себя некрасиво.
    Соответственно, не гарантируется корректность обратной связи: кто сказал, что сериализованные данные от вашего приложения будут адекватно распознаны на сервере?

    Как быть?

    Первым на ум приходит подленькое решение подогнать все парсеры и сериализаторы в мобильном приложении под то, что уже приходит с сервера.
    Вы получаете какой-нибудь JSON, вроде этого:

    {
    	data: {
    		“field1”: “value1”,
    		“filed2”: “value2”
    	}
    }
    


    Вместо того, что прописан в спецификации:

    {
    	data: {
    		“entity”: {
    “field1”: “value1”,
    			“filed2”: “value2”
    		}
    	}
    }
    


    Ценная информация – “field1” и “field2” как бы и так приходит. Так почему бы не допустить небольшую хитрость — вычитывать информацию из того, что уже предоставлено?
    Я уже упоминал ключевое слово «консистентность». Дословно с английского «консистентно выполнять» = «последовательно выполнять», в том смысле что «придерживаться заданной линии поведения».

    Например, если изначально какое-то явление было обозвано «phenomenon», то оно и в документации должно именоваться «phenomenon», и в исходном коде должно быть классом «Phenomenon», и в приходящих JSON’ах должно иметь ключ «phenomenon».
    Когда все участники проекта используют один и тот же глоссарий – это значительно снижает риски недопонимания.
    Рано или поздно кто-то из разработчиков может обнаружить несоответствие документации – и исправить. И с другой стороны системы всё обрушится.
    Кроме того, на основе уже написанной документации для сервера впоследствии могут создаваться другие клиенты под другие мобильные и, возможно, desktop-платформы – и они будут натыкаться на эти же проблемы: реализация не соответствует документации.
    Это приведет к тому, что система начнёт обрастать костылями и гнить изнутри.

    Решения


    http://apiary.io

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

    Например, вам необходим сервер, который будет отдавать набор каких-то сущностей Entity. Список пользователей, список ресторанов, список банкоматов – не важно.
    У каждой сущности есть свой ID, по которому сервер должен уметь предоставлять подробную информацию о данной сущности.
    Плюс API должен отдельно предоставлять, скажем, служебную информацию – поле timestamp – время обновления сущности с заданным ID.

    Итак, мы предполагаем, что у нас есть:
    Адрес

    Сервис 1:

    • на GET-запрос отдаёт набор сущностей
    • на POST-запрос отдаёт подтверждение добавления новой сущности

    Сервис 2:

    • на GET-запрос отдаёт подробную информацию о сущности;
    • на UPDATE-запрос отдаёт подтверждение обновления сущности
    (небольшая оговорка: к сожалению, apiary.io не позволяет реализовать полноценный REST, поэтому отдавать на UPDATE-запрос обновлённую сущность вряд ли получится).

    Сервис 3:

    • на GET-запрос отдаёт дату последнего обновления сущности.

    И т.д.

    Пример подобного «сервера» находится здесь.

    Описание макетных сервисов крайне простое и носит декларативный характер.
    При создании нового макетного API вам сразу предоставляется пример:

    FORMAT: 1A
    HOST: http://www.application.com
    
    # application
    Notes API is a *short texts saving* service similar to its physical paper presence on your table.
    
    # Group Notes
    Notes related resources of the **Notes API**
    
    ## Notes Collection [/notes]
    ### List all Notes [GET]
    + Response 200 (application/json)
    
            [{
              "id": 1, "title": "Jogging in park"
            }, {
              "id": 2, "title": "Pick-up posters from post-office"
            }]
    
    ### Create a Note [POST]
    + Request (application/json)
    
            { "title": "Buy cheese and bread for breakfast." }
    
    + Response 201 (application/json)
    
            { "id": 3, "title": "Buy cheese and bread for breakfast." }
    


    Данный код описывает работу сервиса, отвечающего на GET- и POST-запросы.

    И сам сервис apiary.io может выступать в роли прокси. Посредством одного переключателя вы можете перенаправить весь трафик, приходящий на макетный сервер, на «боевой» back-end, не меняя ничего в исходном коде клиента.



    Казалось бы, всё хорошо, всё красиво, сервис позволяет команде работать без блокировки процесса, предоставляет удобный скриптовый язык…
    Проблема в том, что особой логикой он, увы, не обладает.
    Можно сымитировать возвращение сущности в зависимости от её ID, но в любом случае это будет конечный автомат, не способный сколько-нибудь анализировать ситуацию – у него слегка другое предназначение.


    http://www.soapui.org
    Если вам необходимо копнуть чуть глубже – не беда. Всегда есть старый, проверенный Soap UI.

    SoapUI является мультизадачным комбайном, изначально предназначенным и нацеленным на тестирование SOAP- и REST-сервисов в автоматическом режиме. Кроме всего прочего, он сам умеет выступать в роли соответствующего сервера и предоставлять макетные данные.

    Инструкция к действию:
    Создаём проект и выпиливаем из него всё лишнее



    Создаём новый макетный REST-сервис



    Добавляем action



    Пусть возвращает список Entities



    Добавляем макетные данные




    Пусть сервис возвращает этот список только по наличию авторизационного ключа.

    Добавляем ответ для «неавторизованного» пользователя



    Переключаем Dispatch-режим в состояние “SCRIPT” и копируем один из приведенных примеров проверки параметров запроса



    Запускаем (предварительно проверив порт в настройках сервиса; по умолчанию – 8080)



    Проверяем




    Всё, макетный сервер готов.

    Выводы

    Естественно, приведенный сервис – не единственный, и существует ряд его аналогов, типа mockable.io, предоставляющих схожий функционал.
    Увы, у большинства подобных решений обычно недостаёт гибкости в плане реализации полноценной реакции на возможные сетевые запросы.
    Действительно функциональных и удобных сервисов для создания макетных API – не так уж и много.
    С другой стороны, простота подобных решений обеспечивает их относительно быстрое развёртывание, и на каком-то этапе реализации проекта это может стать решающим фактором.
    Так, apiary.io вполне может быть задействован при создании прототипа или proof-of-concept-решения, а по мере эволюционирования проекта уже можно думать о последующем переезде на более продвинутые сервисы с логикой, скриптами…
    А там глядишь – уже и боевой сервер готов.

    Отдельной статьёй, конечно, идут BAAS-сервера, но это уже слегка другая история.

    А как вы решаете проблемы интеграции?
    Redmadrobot
    133,97
    №1 в разработке цифровых решений для бизнеса
    Поделиться публикацией

    Комментарии 3

      +1
      Очень удобно сделать и согласовать схему для JSON и по ней работать. Как для разработчиков сервера прогонять через нее для регрессии так и для клиента проверять на валидность перед выкладкой новой версии АПИ. Вот онлайн генератор схемы www.jsonschema.net/

      Вот тут больше полезных тулов json-schema.org/implementations.html
        0
        Как вариант, можно Протобаф использовать.
          0
          Мы в работе для этих целей используем swagger-ui решение.
          github.com/wordnik/swagger-ui

          Нравится в основном тем, что даёт полную реализацию апи методов и позволяет легко и просто контактировать членам фронт-енд и бэк-енд команд

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

          Самое читаемое