9 Рекомендации по проектированию слоя сервисов Обзор При предоставлении доступа к функциональности приложения через сервисы функции сервиса должны быть выделены в отдельный слой сервисов. Из данной главы вы поймете, какое место слой сервисов занимает в архитектуре приложения, узнаете, из каких этапов складывается проектирование слоя сервисов, какие шаблоны и технологии используются. В главу также включено руководство по решению типовых проблем, обычно возникающих при проектировании слоя сервисов. В слое сервисов определяется и реализуется интерфейс сервиса и контракты данных (или типы сообщений). Одним из самых важных моментов, о котором нельзя забывать, является то, что сервис никогда не должен раскрывать детали внутренних процессов или бизнес-сущностей, используемых в приложении. В частности, необходимо гарантировать, что сущности бизнесслоя не будут оказывать большого влияния на контракты данных. Слой сервисов должен предоставлять компоненты-трансляторы, которые будут обеспечивать преобразование форматов данных между сущностями бизнес-слоя и контрактами данных. На рис. 1 показано место слоя сервисов в общей архитектуре приложения. Рис. 1 Типовое приложение со слоем сервисов Слой сервисов обычно включает следующие компоненты: Интерфейсы сервисов. Сервисы предоставляют интерфейсы, в которые передаются все входящие сообщения. Интерфейс сервиса можно рассматривать как фасад, предоставляющий потенциальным потребителям доступ к бизнес-логике, реализованной в приложении (как правило, логику бизнес-слоя). Типы сообщений. При обмене данными через слой сервисов структуры данных заключаются в структуры сообщений, поддерживающие разные типы операций. Слой сервисов также обычно включает типы и контракты данных, которые определяют используемые в сообщениях типы данных. Более подробно компоненты, обычно используемые в слое сервисов, рассматриваются в главе 10, «Рекомендации по проектированию компонентов». О проектировании интерфейсов сервисов рассказывает глава 18, «Взаимодействие и обмен сообщениями». Общие принципы проектирования При проектировании слоя сервисов необходимо учесть множество факторов. Многие из этих аспектов проектирования касаются проверенных практик, имеющих отношение к созданию многослойных архитектур. Однако для сервисов необходимо рассматривать также и факторы, связанные с обменом сообщениями. Основное, на что требуется обратить внимание: сервисы взаимодействуют посредством обмена сообщениями, как правило, по сети, что по сути своей медленнее, чем прямое взаимодействие внутри процесса, и обычно сервисы взаимодействуют с потребителями асинхронно. Кроме того, сообщения, передаваемые между сервисом и потребителем, могут быть маршрутизированы, изменены, доставлены в порядке, отличном от порядка, в котором они отправлялись, или даже утрачены, если не реализован механизм гарантированной доставки. Все эти аспекты требуют создания дизайна, в котором будет учтено такое недетерминированное поведение процесса обмена сообщениями. При проектировании слоя сервисов руководствуйтесь следующими рекомендациями: Проектируйте сервисы, областью действия которых является приложение, а не компонент. Операции сервисов должны охватывать большие фрагменты функциональности и сосредотачиваться на операциях приложения. Проектирование слишком узконаправленных операций может иметь негативное влияние на производительность и масштабируемость. Тем не менее, необходимо обеспечить, чтобы сервис не возвращал неограниченно большие объемы данных. Например, для сервиса, который может возвращать большие объемы демографических данных, необходимо создать операцию, которая будет возвращать не все данные за один вызов, а подмножества данных определенного размера. Размер подмножества данных должен соответствовать возможностям сервиса и требованиям его потребителей. Проектируйте расширяемые сервисы и контракты данных, не делая допущений о предполагаемом клиенте. Иначе говоря, контракты данных должны быть спроектированы так, чтобы их можно было расширять, не оказывая влияния на потребителей сервиса. Однако чтобы избежать излишней сложности или для поддержки изменений, не обладающих обратной совместимостью, возможно, придется создавать новые версии интерфейса сервиса, которые будут функционировать параллельно с существующими версиями. Нельзя делать предположения о клиентах или о том, как они планируют использовать предоставляемый сервис. Проектируйте только соответственно контракту сервиса. Слой сервисов должен реализовывать и обеспечивать только функциональность, оговоренную контрактом сервиса. Внутренняя реализация и детали сервиса никогда не должны раскрываться внешним потребителям. Также если возникает необходимость изменить контракт сервиса для включения новой функциональности, реализованной сервисом, и новые операции и типы не являются обратно совместимыми с существующими контрактами, рассмотрите возможность создания версий контрактов. Определите новые операции, предоставляемые сервисом в новой версии контракта сервиса, и новые типы передаваемых сообщений в новой версии контракта данных. Проектирование контрактов сообщений рассматривается в главе 18, «Взаимодействие и обмен сообщениями». Отделяйте функциональность слоя сервиса от функциональности инфраструктуры. В слое сервисов реализация сквозной функциональность не должен сочетаться с кодом логики сервиса, поскольку это может усложнить расширение и обслуживание реализаций. Обычно сквозная функциональности реализуется в отдельных компонентах, доступных для компонентов бизнес-слоя. Создавайте сущности из стандартных элементов. По возможности компонуйте сложные типы и объекты передачи данных, используемые сервисом, из стандартных элементов. При проектировании учитывайте возможность поступления некорректных запросов. Никогда нельзя делать предположение о том, что все поступающие в сервис сообщения будут корректными. Реализуйте логику валидации всех входных данных на основании значений, диапазонов и типов данных, и отклоняйте недопустимые данные. Более подробно валидация рассматривается в главе 17, «Сквозная функциональность». Обеспечьте в сервисе функциональность для выявления и обработки повторяющихся сообщений (идемпотентность). Реализация широко известных шаблонов, таких как Receiver и Replay Protection, при проектировании сервиса обеспечит, что дублирующие сообщения не будут обрабатываться, или что повторная обработка не будет влиять на результат. Проектируйте сервис, чтобы он мог обрабатывать сообщения, поступающие в произвольном порядке (коммутативность). Если существует вероятность поступления сообщений в порядке, отличном от того, в котором они отправлялись, реализуйте возможность сохранения сообщений с последующей обработкой в правильном порядке. Специальные вопросы проектирования Существует ряд общих вопросов, на которые следует обратить внимание при проектировании слоя сервисов. Эти вопросы можно сгруппировать по определенным областям дизайна. В следующих разделах представлены рекомендации по проектированию аспектов, в которых чаще всего возникают ошибки: Аутентификация Авторизация Сетевое взаимодействие Управление исключениями Каналы обмена сообщениями Структура сообщения Конечная точка сообщения Безопасность сообщений Маршрутизация сообщений Преобразование сообщений Интерфейс сервиса Валидация Более подробно протоколы сообщений, асинхронная связь, возможность взаимодействия, производительность и доступные технологии рассматриваются в главе 18, «Взаимодействие и обмен сообщениями». Аутентификация Аутентификация используется для установления подлинности потребителя сервиса. Проектирование эффективной стратегии аутентификации для слоя сервисов имеет большое значение с точки зрения обеспечения безопасности и надежности приложения, в противном случае, оно будет уязвимым для атак с подделкой пакетов, атак перебором по словарю, перехватом сеансов и других типов атак. При проектировании стратегии аутентификации руководствуйтесь следующими рекомендациями Найдите походящий механизм безопасно идентифицировать пользователей, по возможности используя функции базовой платформы, и определите границы доверия, при пересечении которых должна применяться аутентификация. Учтите последствия применения разных настроек уровней доверия для выполнения кода сервиса. Для обычной аутентификации или при передаче учетных данных в открытом виде используйте такие безопасные протоколы, как Secure Sockets Layer (SSL). Для SOAPсообщений применяйте механизмы безопасности уровня сообщения, поддерживаемые стандартами WS* (Web Services Security, Web Services Trust и Web Services Secure Conversation). Авторизация Авторизация позволяет определить, какие ресурсы или действия доступны тому или иному аутентифицированному потребителю сервиса. Проектирование эффективной стратегии авторизации для слоя сервисов имеет большое значение с точки зрения обеспечения безопасности и надежности приложения, в противном случае, оно будет уязвимым для разглашения сведений, повреждения или подделки данных и несанкционированного получения прав. Как правило, стратегия авторизации работает с обобщенными действиями или операциями, а не ресурсами, которые их выполняют. При проектировании стратегии авторизации руководствуйтесь следующими рекомендациями: Задайте соответствующие права доступа к ресурсам для пользователей, групп и ролей. Выполняйте сервисы под учетной записью, обладающей лишь необходимым набором разрешений. По возможности избегайте слишком подробного деления прав при авторизации, чтобы обеспечить эффективность и удобство обслуживания применяемой стратеги авторизации. Для аутентификации Windows используйте авторизацию URL и/или авторизацию доступа к файлам. Где это возможно, ограничьте доступ к открытым Веб-методам путем использования декларативных методов проверки прав. Сетевое взаимодействие При проектировании стратегии сетевого взаимодействия для сервиса выбор протокола должен основываться на сценарии развертывания, который должен поддерживать ваш сервис. При проектировании стратегии связи руководствуйтесь следующими рекомендациями На основании требований, предъявляемых к механизмам сетевого взаимодействия, определите используемый механизм: запрос-ответ или двусторонняя связь, и то, должен ли обмен сообщениями быть однонаправленным или двунаправленным. Также выясните необходимость в асинхронных вызовах. Примите решение о том, как будет обрабатываться ненадежная или неустойчивая связь, возможно, путем реализации агента сервиса или использования надежной системы очереди сообщений, такой как Message Queuing. Если сервис предполагается развертывать в закрытой сети, используйте протокол Transmission Control Protocol (TCP)1, что обеспечит максимальную эффективность сетевого взаимодействия. Если сервис будет развертываться в Интернете, используйте протокол Hypertext Transfer Protocol (HTTP)2. Для обеспечения максимальной гибкости используйте динамические URL для конфигурации конечных точек. Например, вместо указания URL конечных точек в коде, по возможности используйте конфигурацию или сервис каталогов, такой как Universal Discovery Description and Integration (UDDI)3. Проверяйте адреса конечных точек и обеспечьте защиту конфиденциальных данных в сообщениях. Управление исключениями Проектирование эффективной стратегии управления исключениями для слоя сервисов имеет большое значение с точки зрения обеспечения безопасности и надежности приложения, в противном случае, оно будет уязвимым для атак Отказа в обслуживании (Denial of Service, DoS) и может допустить разглашение конфиденциальных или наиболее важных данных о приложении. Формирование и обработка исключений является ресурсоемкой операцией, поэтому важно, чтобы проектирование стратегии управления исключениями велось с учетом влияния на производительность. Хорошей практикой является проектирование 1 Протокол управления передачей (прим. переводчика). 2 Протокол передачи гипертекста (прим. переводчика). 3 Универсальный поиск, описание и взаимодействие (прим. переводчика). централизованного механизма управления исключениями и протоколирования. Также предусмотрите механизмы управления, поддерживающие инструментирование и централизованный мониторинг, чтобы облегчить работу системным администраторам. При проектировании стратегии управления исключениями руководствуйтесь следующими рекомендациями: Перехватывайте только те исключения, которые можете обработать, и продумайте, как обеспечить целостность сообщения при возникновении исключения. Обеспечьте корректную обработку необрабатываемых исключений и не используйте исключения для управления бизнес-логикой. При работе с SOAP используйте элементы Fault (Сбой) или специальные расширения для доставки данных исключения вызывающей стороне. Обеспечьте протоколирование исключений, обеспечивающее неразглашение конфиденциальных данных в сообщениях об ошибках или файлах журнала. Более подробно методики управления исключениями рассматриваются в главе 17, «Сквозная функциональность». Каналы обмена сообщениями Связь между сервисом и его потребителями состоит в передаче данных по каналу. В большинстве случаев используются каналы, предоставляемые выбранной инфраструктурой сервиса, такой как Windows Communication Foundation (WCF). Необходимо понимать, какие шаблоны поддерживает выбранная инфраструктура, и определить подходящий канал для взаимодействия с потребителями сервиса. При проектировании каналов обмена сообщениями руководствуйтесь следующими рекомендациями: Из имеющихся шаблонов каналов обмена сообщениями, таких как Channel Adapter, Messaging Bus и Messaging Bridge, выберите наиболее подходящие для вашего сценария. Убедитесь также в правильности выбора инфраструктуры сервисов и ее соответствии всем требованиям. Продумайте, как будете перехватывать и проверять данные между конечными точками, если в этом появится необходимость. Опишите условия возникновения исключений в канале и способы их обработки. Продумайте, как будете обеспечивать доступ к клиентам, не поддерживающим обмен сообщениями. Структура сообщения Данные, которыми обмениваются сервис и его потребитель, должны быть заключены в сообщение. Формат этого сообщения определяется типами поддерживаемых операций. Например, может происходить обмен документами, выполнение команд или формирование событий. При проектировании структуры сообщения руководствуйтесь следующими рекомендациями: Из имеющихся шаблонов структуры сообщения, таких как Command, Document, Event и Request-Reply, выберите наиболее подходящие для вашего сценария. Разделяйте очень большие объемы данных на меньшие блоки и отправляйте их последовательно. При использовании медленных каналов доставки сообщений включайте в сообщения данные о сроке действия. Сервис должен игнорировать сообщения, срок действия которых истек. Конечная точка для передачи сообщения Конечная точка для передачи сообщения представляет подключение, которое приложения используют для взаимодействия с сервисом. Реализация интерфейса сервиса представляет конечную точку для передачи сообщений. При проектировании реализации сервиса необходимо учесть возможность поступления дублирующихся или недействительных сообщений. При проектировании конечных точек для передачи сообщений руководствуйтесь следующими рекомендациями: Из доступных шаблонов конечных точек для передачи сообщений, таких как Gateway, Mapper, Competing Consumers и Message Dispatcher, выберите наиболее подходящие вашему сценарию. Определитесь с тем, должны ли приниматься все сообщения или необходимо реализовать фильтр для обработки лишь определенных сообщений. Обеспечьте идемпотентность интерфейса для передачи сообщений. Идемпотентность – это ситуация, когда при поступлении от одного потребителя дублирующихся сообщений обрабатывается только одно из них. Иначе говоря, идемпотентная конечная точка гарантирует, что будет обработано только одно сообщение и все дублирующиеся сообщения будут проигнорированы. Обеспечьте коммутативность интерфейса для передачи сообщений. Коммутативность касается порядка приема сообщений. В некоторых случаях может понадобиться сохранять входящие сообщения, чтобы обеспечить их обработку в правильном порядке. Проектируйте с учетом сценариев без постоянного подключения. Например, реализуйте поддержку гарантированной доставки или сохранения сообщений для отложенной доставки. Обеспечьте, чтобы при отсутствии подключения не выполнялись попытки соединения с конечными точками. Безопасность сообщений При передаче конфиденциальных данных между сервисом и его потребителем необходимо предусмотреть защиту сообщений. Можно использовать защиту на транспортном уровне (IPSec или SSL) или защиту на уровне сообщения (шифрование и цифровые подписи). При проектировании безопасности сообщений руководствуйтесь следующими рекомендациями: В большинстве случаев необходимо предусмотреть возможности защиты содержимого сообщений методами обеспечения безопасности на уровне сообщения. Безопасность на уровне сообщения помогает защищать конфиденциальные данные, передаваемые в сообщениях, путем их шифрования и предоставления цифровой подписи, которая защитит от повреждений или подделки сообщений, а также позволит выявить отправителя сообщения. Однако нельзя забывать, что каждый уровень защиты негативно сказывается на производительности. Если взаимодействие между сервисом и потребителем осуществляется без посредников, таких как другие серверы и маршрутизаторы, можно использовать защиту на транспортном уровне, например, с помощью протоколов IPSec или SSL. Но если сообщение передается через одного или более посредников, должна использоваться только безопасность на уровне сообщения, поскольку при первом варианте защиты сообщение дешифруется и затем повторно шифруется на каждом посреднике, что представляет угрозу безопасности. Применение обоих типов защиты, и на транспортном уровне, и на уровне сообщений, обеспечит максимальную безопасность. Безопасность на транспортном уровне поможет защитить данные заголовков, которые не могут быть зашифрованы при использовании безопасности на уровне сообщений. Маршрутизация сообщений Маршрутизатор сообщений обеспечивает отделение потребителя сервиса от реализации сервиса. Существует три основных типа марштутизаторов: простые, составные и шаблонные. В простых маршрутизаторах конечная точка назначения сообщения определяется с помощью единственного маршрутизатора. Составные маршрутизаторы объединяют в себе множество простых маршрутизаторов для обработки более сложных потоков сообщений. Архитектурные шаблоны используются для описания разных стилей маршрутизации на основе простых маршрутизаторов сообщений. При проектировании маршрутизации сообщений руководствуйтесь следующими рекомендациями: Из доступных шаблонов маршрутизации сообщений, таких как Aggregator, ContentBased Router, Dynamic Router и Message Filter, выберите наиболее подходящие для вашего сценария. При поступлении от потребителя последовательных сообщений маршрутизатор должен гарантировать их доставку в одну конечную точку в заданном порядке (коммутативность). Маршрутизатор сообщений может просматривать данные сообщения, чтобы понять, как выполнять его маршрутизацию. Таким образом, необходимо гарантировать возможность доступа маршрутизатора к этим данным. Возможно, сведения маршрутизации придется вынести в заголовок. При шифровании сообщения необходимо гарантированно обеспечить, что в нешифрованном заголовке имеются данные, необходимые для маршрутизации сообщения. Преобразование сообщений Часто при передаче сообщений между сервисом и потребителем приходится преобразовывать их в формат, понятный потребителю. Обеспечить доступ к каналу обмена сообщениями для клиентов, не поддерживающих обмен сообщениями, можно с помощью адаптеров; а для преобразования данных сообщений в формат, понятный всем потребителям, используются трансляторы. При проектировании преобразования сообщений руководствуйтесь следующими рекомендациями: Определите требования и место выполнения преобразования. Учтите издержки производительности при преобразовании и постарайтесь максимально сократить количество выполняемых преобразований. Выберите соответствующие шаблоны для преобразования сообщений, такие как Canonical Data Mapper, Envelope Wrapper и Normalizer. Однако применяйте модель Canonical Data Mapper только по необходимости. Определяйте формат сообщения с помощью метаданных. Рассмотрите возможность использования внешнего хранилища для хранения метаданных. Интерфейс сервиса Интерфейс сервиса представляет контракт, предоставляемый сервисом. Контракт определяет операции, поддерживаемые сервисом, и связанные с ними параметры и объекты передачи данных. При проектировании интерфейса сервиса необходимо учесть пересекаемые границы и тип потребителей, которые будут осуществлять доступ к сервису. Например, операции сервиса должны быть операциями уровня приложения и слабо детализированными. Одна из самых больших ошибок при проектировании интерфейса сервиса – интерпретация сервиса как компонента с детализированными операциями. Это приводит к созданию дизайна, требующего большого количества вызовов через физические границы или границы процесса, что может снизить производительность и увеличить задержки при выполнении операций. При проектировании интерфейса сервиса руководствуйтесь следующими рекомендациями: Используйте слабо детализированный интерфейс для обеспечения пакетирования запросов и максимального сокращения количества вызовов по сети. Проектируйте интерфейсы сервисов таким образом, чтобы изменения бизнеслогики не оказывали на них влияния. Однако при изменении бизнес-требований, вероятно, это будет просто неизбежно. Не реализуйте бизнес-правила в интерфейсе сервиса. Для обеспечения максимальной совместимости с разными типами клиентов используйте параметры стандартных форматов. При проектировании интерфейса не делайте допущений о возможных вариантах использования сервиса клиентом. Не используйте наследование объектов для реализации контроля версий интерфейса сервиса. Включайте трассировку и компиляцию в режиме отладки для всех сервисов только на время разработки и тестирования. Валидация Для обеспечения защиты слоя сервисов необходимо проверять все получаемые им запросы, в противном случае приложение будет уязвимым и к злонамеренным атакам, и к ошибкам, обусловленным некорректными входными данными. Точного и исчерпывающего определения действительного или злонамеренного ввода не существует, кроме того, риск эксплуатации уязвимостей зависит от того, как приложение использует поступающие данные. При проектировании стратегии валидации руководствуйтесь следующими рекомендациями: Используйте централизованный подход к проверке, чтобы максимально повысить тестируемость и пригодность для повторного использования. Ограничивайте, отклоняйте и очищайте все содержимое сообщений, включая параметры. Проводите проверку длины, диапазона, формата и типа. Используйте схемы проверки сообщений. Валидация с применением схем рассматривается в статье «Message Validation» (Валидация сообщений) по адресу http://msdn.microsoft.com/en-us/library/cc949065.aspx и в статье «Input/Data Validation» (Валидация ввода/данных) по адресу http://msdn.microsoft.com/enus/library/cc949061.aspx. REST и SOAP Representational State Transfer (REST)1 и SOAP представляют два разных стиля реализации сервисов. Фактически, REST – это архитектурный шаблон, создаваемый с использованием простых команд и хорошо ложащийся на протокол HTTP. Хотя архитектурные принципы REST могли бы применяться и с другими протоколами, на практике реализации REST используются в сочетании с HTTP. SOAP – это основанный на XML протокол обмена сообщениями, который может использоваться с любым протоколом связи, в том числе и с HTTP. Основное различие между этими двумя подходами в способе сохранения состояния сервиса. Состояние сервиса не должно рассматриваться как состояние приложения или сеанса; это разные состояния, которые приложение проходит в течение его жизненного цикла. При использовании SOAP переход из состояния в состояние может быть реализован через взаимодействие с единственной конечной точкой сервиса, которая может инкапсулировать и предоставлять доступ ко многим операциям и типам сообщений. При использовании REST набор операций ограничен, и эти операции применяются к ресурсам, которые предоставляются и доступны через URI (HTTP-адреса). В сообщениях фиксируется текущее или необходимое состояние ресурса. REST хорошо работает с Веб-приложениями, что позволяет обеспечивать преимущество поддержки HTTP не-XML MIME-типам или потоковую передачу содержимого. Потребители сервиса при перемещении по REST-ресурсам 1 Передача репрезентативного состояния (прим. переводчика). взаимодействуют с URI так же, как обычный пользователь перемещается и взаимодействует с Веб-страницами. С большинством реализаций сервисов могут использоваться и REST, и SOAP, часто подход с применением REST лучше подходит для публичных сервисов или в случаях, когда доступ к сервису может осуществляться неизвестными потребителями. SOAP намного лучше подходит для реализации широкого диапазона процедурных взаимодействий, таких как интерфейс между слоями приложения. С SOAP вы не ограничены одним только протоколом HTTP. Стандарты WS-*, которые могут использоваться в SOAP, предоставляют стандартный и, следовательно, обеспечивающий возможность взаимодействия метод решения общих проблем обмена сообщениями, таких как безопасность, транзакции, адресация и надежность. REST тоже может обеспечивать такую же функциональность, но в настоящее время эта область практически не стандартизована, поэтому часто приходится создавать собственные механизмы. В общем, при проектировании взаимодействий на базе SOAP можно использовать те же принципы, чтобы и для REST-взаимодействий без сохранения состояния. В обоих подходах для описания обмена данными (полезной нагрузкой) используются обычные глаголы. В случае с SOAP набор глаголов не является окончательным и определяется конечной точкой сервиса. Для REST набор глаголов ограничен предопределенными словами, отражающими протокол HTTP. При выборе между REST и SOAP руководствуйтесь следующими рекомендациями: SOAP – протокол, обеспечивающий базовую инфраструктуру обмена сообщениями, на которой могут строиться абстрактные слои. Он обычно применяется как RPCинфраструктура1, передающая запросы и ответы по сети с помощью XMLформатированных сообщений. SOAP обеспечивает учет таких аспектов, как безопасность и адресация, через внутреннюю реализацию протокола, но требует, чтобы был доступен стек SOAP. REST – методика, которая может использовать другие протоколы, такие как JavaScript Object Notation (JSON)2, протокол публикации Atom и собственные форматы Plain Old XML (POX)3. REST предоставляет приложение и данные как конечный автомат, а не просто конечную точку сервиса. Он позволяет использовать для выполнения запросов и изменения состояния системы стандартные HTTP-методы вызова, такие как GET и PUT. REST по своей природе не сохраняет состояния, поэтому каждый отдельный запрос, присылаемый от клиента серверу, должен содержать все необходимые данные для его интерпретации, поскольку сервер не сохраняет данных о состоянии сеанса. 1 Механизм удаленного вызова процедур (прим. научного редактора). 2 Объектная нотация JavaScript (прим. переводчика). 3 Обычный старый XML (прим. переводчика). Аспекты проектирования при использовании REST REST представляет архитектурный стиль для распределенных систем и создан с целью упростить систему путем ее деления на ресурсы. Ресурсы и операции, поддерживаемые ими, представляются и предоставляются как набор URI, передаваемых по протоколу HTTP. При проектировании REST-ресурсов руководствуйтесь следующими рекомендациями Обозначьте и распределите по категориям ресурсы, которые будут предоставляться клиентам. Выберите подход для представления ресурсов. Хорошей практикой является использование значащих имен для исходных точек REST и уникальных идентификаторов для конкретных экземпляров ресурсов. Например, http://www.contoso.com/employee/ представляет исходную точку служащий. http://www.contoso.com/employee/smithah01 использует ID служащего для обозначения конкретного служащего. Примите решение о необходимости поддержки множества реализаций для разных ресурсов. Например, о том, должен ли ресурс поддерживать форматы XML, Atom или JSON, и сделайте это частью запроса к ресурсу, тогда ресурс будет предоставляться в разных форматах (например, http://www.contoso.com/example.atom и http://www.contoso.com/example.json). Примите решение о необходимости поддерживать множество представлений для разных ресурсов. Например, должен ли ресурс поддерживать операции GET и POST или только GET. По возможности не увлекайтесь применением операций POST и избегайте размещения действий в URI. Не реализуйте сохранения состояния сеанса пользователя в сервисе и не пытайтесь использовать гипертекст (такой как скрытые элементы управления в Веб-страницах) для управления состоянием. Например, когда пользователь передает запросы, например, для добавления элемента в корзину, сохраняйте данные в постоянном хранилище, таком как база данных. Аспекты проектирования при использовании SOAP SOAP – основанный на сообщениях протокол, используемый для реализации слоя обмена сообщениями сервиса. Сообщение представляет собой конверт, в котором содержатся заголовок и тело. Заголовок может использоваться для предоставления сведений, внешних по отношению к операции, осуществляемой сервисом. Например, в заголовок могут быть включены данные безопасности, транзакции или маршрутизации. Тело включает контракты в форме XML-схем, используемые для реализации сервиса. При проектировании SOAPсообщений руководствуйтесь следующими рекомендациями: Примите решение о том, как будут обрабатываться сбои и ошибки, и как будут возвращаться клиентам соответствующие сведения об ошибке. Более подробно эти вопросы рассматриваются в статье «Exception Handling in Service Oriented Applications» (Обработка исключений в сервисно-ориентированных приложениях) по адресу http://msdn.microsoft.com/en-us/library/cc304819.aspx. Определите набор операций, осуществляемых сервисом; структуры данных, передаваемые с запросом к сервису; и ошибки или сбои, возвращаемые запросом к сервису. Выберите соответствующую модель безопасности для сервисов. Более подробно эти вопросы рассматриваются в статье «Improving Web Services Security: Scenarios and Implementation Guidance for WCF» (Повышение безопасности Веб-сервисов: сценарии и руководство по реализации для WCF) по адресу http://msdn.microsoft.com/en-us/library/cc949034.aspx. Избегайте использования составных типов в сообщениях. Применение только простых типов обеспечит максимальную возможность взаимодействия. Более подробно REST и SOAP рассматриваются в главе 25, «Проектирование приложений сервисов». Вопросы выбора технологий Следующие рекомендации помогут правильно выбрать технологию для реализации слоя сервисов: 1 Для простоты используйте ASP.NET Web services (ASMX), но только если доступен Веб-сервер, работающий под управлением Microsoft Internet Information Services (IIS). Используйте сервисы WCF, если требуется реализовать расширенные возможности, такие как надежные сеансы с гарантированной доставкой сообщений и транзакции, трассировка действий, протоколирование сообщений, счетчики производительности и поддержка нескольких транспортных протоколов. Если для сервиса решено использовать ASMX и требуется обеспечить безопасность на уровне сообщения и передачу двоичных данных, можно применить Web Service Extensions (WSE)1. Однако, как правило, в случае необходимости реализации функциональность WSE следует переходить к WCF. Если решено использовать WCF для сервиса: ◦ Используйте HTTP-транспорт на базе спецификаций SOAP для обеспечения возможности взаимодействия с не-WCF и не-Windows клиентами. ◦ Используйте протокол TCP и двоичное кодирование сообщений с безопасностью на транспортном уровне и аутентификацией Windows, если требуется поддерживать клиентов во внутренней сети. ◦ Используйте протокол именованных каналов и бинарное кодирование сообщений, если требуется поддерживать WCF-клиентов, размещенных на том же компьютере. Расширения Веб-сервисов (прим. переводчика). ◦ Определяйте контракты сервисов, которые используют явную, а не неявную, оболочку сообщений. Это позволит определять контракты сообщений как вход и выход для операций, таким образом, вы сможете расширять контракты данных, включенные в контракты сообщения, не оказывая влияния на контракт сервиса. Доступные технологии обмена сообщениями представлены в главе 18, «Взаимодействие и обмен сообщениями». Вопросы развертывания Слой сервисов может развертываться на одном уровне с другими слоями приложения или на разных уровнях, если это обусловлено требованиями производительности и изоляции. Тем не менее, в большинстве случаев слой сервисов располагается физически на одном уровне с бизнес-слоем, это позволяет обеспечить наилучшую производительность при предоставлении бизнес-функциональности. При развертывании слоя сервисов руководствуйтесь следующими рекомендациями: Если это не идет в разрез с требованиями производительности и безопасности среды производственной эксплуатации, развертывайте слой сервисов на одном уровне с бизнес-слоем, это обеспечит максимальную производительность приложения. Если сервис размещается на одном уровне с потребителем сервиса, используйте именованные каналы или протоколы общей памяти. Если сервис используется только приложениями локальной сети, используйте для взаимодействия протокол TCP. Если сервис публично доступен через Интернет, используйте HTTP в качестве транспортного протокола Более подробно схемы развертывания рассматриваются в главе 19, «Физические уровни и развертывание». Этапы проектирования слоя сервисов Проектирование слоя сервисов начинается с определения интерфейса сервиса, состоящего из контрактов, которые планируется предоставлять. Обычно такой подход называют Contract First Design (Контрактно-ориентированное проектирование). Следующий шаг после определения интерфейса сервиса – проектирование реализации сервиса, который используется для преобразования контрактов данных в бизнес-сущности и для взаимодействия с бизнес-слоем. Проектирование слоя сервисов может включать следующие основные этапы: 1. Определение контрактов данных и сообщений, которые представляют используемую для сообщений схему. 2. Определение контрактов сервиса, которые представляют операции, поддерживаемые сервисом. 3. Определение контрактов сбоев, которые возвращают данные об ошибках потребителям сервиса. 4. Проектирование объектов преобразований, которые обеспечивают преобразования между бизнес-сущностями и контрактами данных. 5. Проектирования абстракции, используемой для взаимодействия с бизнес-слоем. Для разработки Веб-сервисов можно использовать инструменты проектирования, такие как Web Service Software Factory: Modeling Edition (также известный как Service Factory) от группы patterns & practices. Этот интегрированный набор ресурсов создан с целью обеспечить возможность быстро и единообразно создавать Веб-сервисы с использованием широко известных архитектурных схем и шаблонов проектирования. Более подробно данные вопросы рассматриваются в статье «Web Service Software Factory: Modeling Edition» (Фабрика ПО для разработки Веб-сервисов: издание для построения моделей) по адресу http://msdn.microsoft.com/en-us/library/cc487895.aspx. Проектирование контрактов сообщений и подход Contract-First рассматриваются в главе 18, «Взаимодействие и обмен сообщениями». Абстракции в многослойных архитектурах посвящена глава 5, «Рекомендации по проектированию многослойных приложений». Шаблоны проектирования Основные шаблоны организованы по категориям и представлены в следующей таблице. Рассмотрите возможности применения этих шаблонов при принятии проектных решений для каждой из категорий. Категория Шаблоны проектирования Сетевое взаимодействие Duplex (Двусторонний обмен сообщениями). Двунаправленный обмен сообщениями, при котором и сервис, и клиент отправляют сообщения друг другу независимо и без учета того, какой шаблон используется, OneWay (Однонаправленный) или Request-Reply (Запрос-ответ). Fire and Forget (Отправил и забыл). Однонаправленный обмен сообщениями, используемый, когда ожидать ответа нет необходимости. Reliable Sessions (Надежные сеансы). Надежная передача сообщений из конца в конец между источником и точкой назначения, не зависящая от количества или типа посредников между конечными точками. Request Response (Запрос-ответ). Механизм двунаправленного обмена сообщениями, при котором клиент ожидает ответа на каждое отправленное сообщение. Каналы обмена сообщениями Channel Adapter (Адаптер канала). Компонент, который может выполнять доступ к API или данным приложения и на основании этих данных публиковать сообщения в канале, а также может принимать сообщения и вызывать функции приложения. Message Bus (Шина сообщений). Структурирует связующее промежуточное ПО между приложениями как шину связи, что позволяет приложениям взаимодействовать, используя обмен сообщениями. Messaging Bridge (Мост обмена сообщениями). Компонент, соединяющий обменивающиеся сообщениями системы и тиражирующий сообщения между этими системами. Point-to-Point Channel (Канал «точка-точка»). Передача сообщения по каналу «точка-точка» гарантирует, что получит это конкретное сообщение только один получатель. Publish-Subscribe Channel (Канал публикации-подписки). Создает механизм отправки сообщений только приложениям, заинтересованным в получении этих сообщений, без идентификации получателей. Структура сообщения Command Message (Сообщение с командой). Структура сообщения, используемая для поддержки команд. Document Message (Сообщение с данными документа). Структура, используемая для передачи документов или структуры данных между приложениями. Event Message (Сообщение о событии). Структура, обеспечивающая надежное асинхронное уведомление о событиях между приложениями. Request-Reply (Запрос-отклик). Запрос и отклик передаются по разным каналам. Конечная точка сообщения Competing Consumer (Конкурирующий потребитель). Задает несколько потребителей для одной очереди сообщений и заставляет их конкурировать за право обрабатывать сообщения, что позволяет обменивающемуся сообщениями клиенту обрабатывать множество сообщений одновременно. Durable Subscriber (Постоянный подписчик). Чтобы обеспечить гарантированную доставку в сценарии без подключения, сообщения сохраняются и затем предоставляются для доступа клиенту при подключении к каналу сообщений. Idempotent Receiver (Идемпотентный получатель). Гарантирует, что сервис обрабатывает сообщение только один раз. Message Dispatcher (Диспетчер сообщений). Компонент, рассылающий сообщения множеству потребителей. Messaging Gateway (Шлюз обмена сообщениями). Инкапсулирует вызовы, осуществляемые посредством обмена сообщениями, в один интерфейс, чтобы отделить их от остального кода приложения. Messaging Mapper (Преобразователь обмена сообщениями). Преобразует запросы в бизнес-объекты для входящих сообщений и выполняет обратный процесс для преобразования бизнес-объектов в ответные сообщения. Polling Consumer (Опрашивающий потребитель). Потребитель сервиса, который проверяет канал на наличие сообщений через равные промежутки времени. Selective Consumer (Избирательный потребитель). Потребитель сервиса, использующий фильтры для поучения только сообщений, соответствующих определенному критерию. Service Activator (Активатор сервиса). Сервис, принимающий асинхронные запросы для вызова операций в компонентах бизнес-слоя. Transactional Client (Транзакционный клиент). Клиент, который может реализовать транзакции при взаимодействии с сервисом. Безопасность Data Confidentiality (Конфиденциальность данных). Использует сообщений шифрование на уровне сообщений для защиты конфиденциальных данных в сообщении. Data Integrity (Целостность данных). Гарантированно обеспечивает защиту сообщений от повреждения или подделки при передаче. Data Origin Authentication (Аутентификация происхождения данных). Проводит проверку источника сообщения как расширенный метод обеспечения целостности данных. Exception Shielding (Экранирование исключений). При возникновении исключения предотвращает разглашение сервисом данных о его внутренней реализации. Federation (Объединение). Интегрированное представление данных, распределенных по многим сервисам и потребителям. Replay Protection (Защита от атак повторов). Обеспечивает идемпотентность сообщения, предотвращая возможность его перехвата и многократного выполнения злоумышленниками. Validation (Валидация). Проверяет содержимое и значения сообщений для обеспечения защиты сервиса от неправильно сформированного или злонамеренного содержимого. Маршрутизация сообщения Aggregator (Агрегатор). Фильтр, обеспечивающий сбор и сохранение взаимосвязанных сообщений, объединение этих сообщений и публикацию в выходном канале одного агрегатного сообщения для дальнейшей обработки. Content-Based Router (Маршрутизатор на основе содержимого). Выполняет маршрутизацию каждого сообщения к соответствующему потребителю, исходя из содержимого сообщения, например, наличия определенных полей, заданных значений полей и т.д. Dynamic Router (Динамический маршрутизатор). Компонент, выполняющий динамическую маршрутизацию сообщения к потребителю на основании оценки условий/правил, заданных потребителем. Message Broker (Hub and Spoke) (Брокер сообщений (веерная структура)). Центральный компонент, взаимодействующий с множеством приложений для получения сообщений из многих источников; определяет место назначения сообщения и направляет его в соответствующий канал. Message Filter (Фильтр сообщений). На основании заданных критериев предотвращает передачу по каналу потребителю нежелательных сообщений. Process Manager (Диспетчер процесса). Компонент, обеспечивающий маршрутизацию сообщений через множество этапов рабочего процесса. Преобразование сообщения Canonical Data Mapper (Канонический преобразователь данных). Использует общий формат данных для осуществления преобразований между двумя несопоставимыми форматами данных. Claim Check (Проверка утверждений). Извлекает данные из постоянного хранилища по необходимости. Content Enricher (Расширитель содержимого). Дополняет сообщения недостающими данными, полученными из внешнего источника данных. Content Filter (Фильтр содержимого). Удаляет конфиденциальные данные из сообщения и максимально сокращает объем сетевого трафика, удаляя ненужные данные из сообщения. Envelope Wrapper (Оболочка конверта). Оболочка сообщений, включающая данные заголовка, используемые, например, для защиты, маршрутизации или аутентификации сообщения. Normalizer (Нормализатор). Преобразует или трансформирует данные в общий формат обмена, если организации используют разные форматы. REST Behavior (Поведение). Применяется к ресурсам, выполняющим операции. Обычно такие ресурсы не содержат состояния и поддерживают только операцию POST. Container (Контейнер). Создает шаблон сущности, обеспечивая средства для динамического добавления и/или обновления вложенных ресурсов. Entity (Сущность). Ресурсы, чтение которых может быть осуществлено операцией GET, но изменение возможно только с помощью операций PUT и DELETE. Store (Хранилище). Обеспечивает возможность создания и обновления сущностей с помощью операции PUT. Transaction (Транзакция). Ресурсы, поддерживающие транзакционные операции. Интерфейс сервиса Façade (Фасад). Реализует унифицированный интерфейс для набора операций, чтобы обеспечить упрощенный интерфейс и уменьшить связанность систем. Remote Façade (Удаленный фасад). Создает обобщенный унифицированный интерфейс для набора операций или процессов в удаленной подсистеме, обеспечивая обобщенный интерфейс для детализированных операций, чтобы упростить использование этой подсистемы и свести до минимума вызовы по сети. Service Interface (Интерфейс сервиса). Программный интерфейс, который может использоваться другими системами для взаимодействия с сервисом. SOAP Data Contract (Контракт данных). Схема, определяющая структуры данных, передаваемые с запросом к сервису. Fault Contracts (Контракты сбоев). Схема, определяющая ошибки или сбои, которые могут быть возвращены из запроса к сервису. Service Contract (Контракт сервиса). Схема, определяющая операции, которые может осуществлять сервис. Более подробно шаблоны Duplex и Request Response рассматриваются в статье «Designing Service Contracts» (Проектирование контрактов сервисов) по адресу http://msdn.microsoft.com/en-us/library/ms733070.aspx. Более подробно шаблон Request-Reply рассматривается в статье «Request-Reply» (Запросответ) по адресу http://www.eaipatterns.com/RequestReply.html. Более подробно шаблоны Command, Document Message, Event Message, Durable Subscriber, Idempotent Receiver, Polling Consumer и Transactional Client рассматриваются в статье «Messaging Patterns in Service-Oriented Architecture, Part I» (Шаблоны обмена сообщениями в сервисно-ориентированной архитектуре. Часть I) по адресу http://msdn.microsoft.com/enus/library/aa480027.aspx. Более подробно шаблоны Data Confidentiality и Data Origin Authentication рассматриваются в материале «Chapter 2: Message Protection Patterns» (Глава 2: Механизмы защиты сообщений) по адресу http://msdn.microsoft.com/en-us/library/aa480573.aspx. Более подробно шаблоны Replay Detection, Exception Shielding и Validation рассматриваются в материале «Chapter 5: Service Boundary Protection Patterns» (Глава 5: Механизмы защиты границ сервиса) по адресу http://msdn.microsoft.com/en-us/library/aa480597.aspx. Более подробно шаблоны Claim Check, Content Enricher, Content Filter и Envelope Wrapper рассматриваются в материале «Messaging Patterns in Service Oriented Architecture, Part 2» по адресу http://msdn.microsoft.com/en-us/library/aa480061.aspx. Более подробно шаблон Remote Façade рассматриваются в статье «Patterns of Enterprise Application Architecture: Remote Façade» (Архитектура корпоративных программных приложений) по адресу http://martinfowler.com/eaaCatalog/remoteFacade.html. Более подробно шаблоны REST, такие как Behavior, Container и Entity, рассматриваются в статье «REST Patterns» (Шаблоны REST) по адресу http://wiki.developer.mindtouch.com/REST/REST_Patterns. Более подробно шаблоны Aggregator, Content-Based Router, Publish-Subscribe, Message Bus и Point-to-Point рассматриваются в материале «Messaging patterns in Service-Oriented Architecture, Part I» по адресу http://msdn.microsoft.com/en-us/library/aa480027.aspx. Дополнительные источники Электронная версия списка используемых источников доступна по адресу http://www.microsoft.com/architectureguide. «Enterprise Solution Patterns Using Microsoft .NET» по адресу http://msdn.microsoft.com/en-us/library/ms998469.aspx. «Web Service Security Guidance» (Руководство по безопасности Веб-сервисов) по адресу http://msdn.microsoft.com/en-us/library/aa480545.aspx. «Improving Web Services Security: Scenarios and Implementation Guidance for WCF» по адресу http://www.codeplex.com/WCFSecurityGuide. «WS-* Specifications» (Спецификации WS-*) по адресу http://www.wsstandards.com/ws-atomictransaction.asp.