Documentos de Académico
Documentos de Profesional
Documentos de Cultura
REST Las restricciones REST son reglas de diseño que se aplican para establecer las
características distintivas del estilo arquitectónico REST.
Las restricciones formales de REST son:
Cliente-Servidor {393}
Sin estado (Stateless){{395}
Caché {398}
Interfaz / Contrato uniforme {400}
Sistema en capas {404}
Código a pedido {407}
Cada restricción es una decisión de diseño predeterminada que puede tener
impactos tanto positivos como negativos. La intención es que los aspectos positivos de
cada restricción equilibren los aspectos negativos para producir una arquitectura general
que se asemeje a las mejores características de la Web.
Una arquitectura que debilita o elimina una restricción REST dada generalmente se
considera que ya no se ajusta a REST. Desviarse de las restricciones REST puede
resultar en diversas combinaciones de consecuencias positivas y negativas adicionales.
Esto requiere que se tomen decisiones informadas para comprender las posibles
compensaciones cuando se desvía deliberadamente de la aplicación de restricciones
REST.
Cliente-Servidor {393}
Quizás la restricción más fundamental, Cliente-Servidor {393} impone la separación de
El contrato técnico establecido por Interface {400} generalmente está libre de contexto comercial porque, para ser
reutilizable por una amplia gama de servicios y consumidores de servicios, debe proporcionar capacidades
genéricas de alto nivel. que sean lo suficientemente abstractos como para adaptarse a una amplia gama de requisitos
de interacción de servicios. Los datos y el significado específicos de la empresa o del servicio se aíslan en partes
específicas de los mensajes que se intercambian a través del contrato técnico uniforme.
Code-On-Demand {407}
Esta restricción opcional está destinada principalmente a permitir que la lógica dentro de los clientes (como los
navegadores web) se actualice independientemente de la lógica del lado del servidor. Code-On-Demand {407}
generalmente se basa en el uso de tecnologías basadas en Web, como complementos de navegador Web,
subprogramas o lenguajes de programación del lado del cliente (es decir, JavaScript). Code-On-Demand {407}
también se puede aplicar a servicios y consumidores de servicios. Por ejemplo, un servicio puede diseñarse para
diferir dinámicamente partes de la lógica a los programas de los consumidores de servicios. Por ejemplo, este tipo
de funcionalidad se puede usar en apoyo de Stateless {395}, que dicta cuándo el estado de la sesión debe ser
aplazado al consumidor del servicio. Code-On-Demand {407} también puede basarse en esto posponiendo aún más
el esfuerzo de procesamiento. Este enfoque puede justificarse cuando el consumidor puede ejecutar la lógica del
servicio de manera más eficiente o eficaz.
Rendimiento
Dos características fundamentales que distinguen las arquitecturas distribuidas de las
diseñadas para funcionar en una sola máquina son el rendimiento y la fiabilidad de la
comunicación. Con el rendimiento, debemos lidiar con problemas como la latencia de la
red y el ancho de banda limitado de la red. Las redes no confiables también pueden
afectar el rendimiento al perder, reordenar o retrasar paquetes o mensajes, y requerir
que se vuelvan a intentar o reenviar.
A menudo pensamos en el rendimiento de la red como absoluto, pero está impulsado
por una serie de factores, algunos de los cuales se ven afectados por decisiones
arquitectónicas. En primer lugar, está la cuestión de qué datos realmente se deben
transferir a través de la red. Los datos deben moverse si se necesitan para su
procesamiento en una ubicación diferente de donde se almacenan. Por lo tanto, las
arquitecturas que mantienen los datos cerca de donde se procesan, naturalmente,
funcionan mejor que las que tienen que moverlos antes de que puedan procesarse.
Una vez que está claro que todos los flujos de datos son esenciales, la siguiente
pregunta es cómo ocurren esos flujos y qué tipo de gastos generales están involucrados.
Cuantos menos mensajes y viajes de ida y vuelta a través de la red se realicen para
transferir los datos y menos gastos generales se incluyan en esos mensajes, más
eficiente será la transferencia (Figura 5.5). Se puede incurrir en sobrecarga de protocolo
cuando se inicia una interacción o se establece una conexión, y cuando cada mensaje o
paquete se envía como parte de la interacción. La sobrecarga también se puede
introducir transfiriendo datos irrelevantes que no serán utilizados por su destinatario
cuando se inicie una interacción o se establezca una conexión, y cuando cada mensaje
o paquete se envíe como parte de la interacción. Los gastos generales también se
pueden introducir transfiriendo datos irrelevantes que no serán utilizados por su
destinatario.
Las arquitecturas de estilo REST admiten el equilibrio de carga en todas las instancias
de servicio a través de las restricciones del sistema en capas {404} y del contrato
uniforme {400}. Estas restricciones permiten que los servicios utilicen soluciones de
equilibrio de carga listas para usar como primer nivel en el manejo de solicitudes en
nombre de un servicio sin cambiar su contrato de servicio técnico. Esto se puede
simplificar aún más mediante la restricción Stateless {395}, que estructura las
interacciones como pares de solicitud-respuesta que pueden ser manejados por servicios
independientemente de otras solicitudes. No es necesario seguir dirigiendo al mismo
consumidor de servicios a la misma instancia de servicio o sincronizar explícitamente el
estado de la sesión entre instancias de servicio; los datos de la sesión están contenidos
en cada solicitud.
Simplicidad
La arquitectura distribuida de una solución está idealmente diseñada para reducir la
complejidad al separar la funcionalidad de tal manera que cada unidad de funcionalidad
sea distinta y fácil de entender. El objetivo del diseño de simplicidad se basa en la
aplicación adecuada de la separación de preocupaciones.
La simplicidad es un enfoque para REST porque afecta la forma en que los servicios se
definen, descubren y eventualmente se usan (o reutilizan) y determina aún más la
facilidad con la que los servicios pueden evolucionar de forma independiente.
La aplicación del contrato uniforme {400} da como resultado una arquitectura en la que
cada interacción entre servicios, consumidores y middleware utiliza los mismos tipos de
mensajes. La aplicación de Stateless {395} permite que cada solicitud se entienda por
derecho propio sin necesidad de hacer referencia a mensajes anteriores que se enviaron
como parte de la misma sesión. Las restricciones Cliente-Servidor {393} y Sistema en
capas {404} dan como resultado la lógica del servicio, la lógica del consumidor y la
lógica del middleware que solo deben entenderse mediante contratos técnicos definidos.
Modificabilidad
Los requisitos para una arquitectura tecnológica están destinados a cambiar con el
tiempo. La modificabilidad representa la facilidad con la que se pueden realizar
cambios en una arquitectura.
La modificabilidad en una arquitectura de estilo REST se divide en las siguientes áreas:
capacidad de evolución: la capacidad de refactorizar y volver a implementar un
servicio, consumidor o componente de middleware sin afectar otras partes de la
arquitectura (incluso cuando la actualización se produce mientras las
aplicaciones se están ejecutando )
Fiabilidad
La confiabilidad de una arquitectura distribuida es el grado en que sus soluciones y
servicios (y la infraestructura subyacente) son susceptibles de fallar. La confiabilidad de
una arquitectura se puede mejorar evitando puntos únicos de falla, utilizando
mecanismos de conmutación por error y confiando en funciones de monitoreo que
pueden anticipar y responder dinámicamente a las condiciones de falla.
Soa
Diseño orientado a servicios
La fase de diseño orientado a servicios representa una etapa del ciclo de vida de la
prestación de servicios dedicada a producir contratos de servicio en apoyo del enfoque
bien establecido de "contrato primero" para el desarrollo de software.
El punto de partida típico para el proceso de diseño orientado a servicios es un
candidato de servicio que se produjo como resultado de completar todas las iteraciones
requeridas del proceso de análisis orientado a servicios . El diseño orientado al servicio
somete a este candidato a servicio a consideraciones adicionales que lo configuran en
un contrato de servicio técnico en alineación con otros contratos de servicio que se
producen para el mismo inventario de servicios.
Existe un proceso de diseño orientado al servicio diferente para cada uno de los tres
modelos de servicio comunes (tarea, entidad y utilidad). Las variaciones en los pasos
del proceso se adaptan principalmente a diferentes prioridades y la naturaleza de la
lógica que expresa el contrato.
Este libro no analiza el proceso de diseño orientado a servicios en detalle, pero hay
referencias a algunas de las consideraciones planteadas por el énfasis de "contrato
primero" de este proceso.
Servicio web
Un servicio web es un cuerpo de lógica de solución que proporciona un
contrato técnico desacoplado físicamente que consta de una definición WSDL y una o
más definiciones de esquema XML y / o
política WS . Como exploraremos en este libro, estos documentos pueden existir en un
archivo físico o estar distribuidos en varios archivos y seguir siendo parte de un
contrato de servicio.
Distribuirlos los hace reutilizables en múltiples contratos.
El contrato de servicio web expone las capacidades públicas como operaciones,
estableciendo una
interfaz técnica comparable a una interfaz de programación de aplicaciones (API)
tradicional, pero
sin ningún vínculo con el marco de comunicaciones propietario.
La lógica encapsulada por un servicio web no necesita ser personalizada o
basada en componentes . La lógica de la aplicación heredada, por ejemplo, puede
exponerse a través de contratos de servicios web
mediante el uso de productos de adaptadores de servicios. Cuando se desarrolla a
medida, la lógica del servicio web
se basa normalmente en tecnologías de componentes modernas, como Java y .NET. En
este
caso, los componentes se califican además como lógica de servicio central.
Contrato de
servicio Un contrato de servicio se compone de uno o más documentos publicados que
expresan metainformación
sobre un servicio. La parte fundamental de un contrato de servicio son los
documentos que expresan su interfaz técnica. Estos forman el contrato de servicio
técnico,
que esencialmente establece una API en la funcionalidad ofrecida por el servicio a
través de sus
capacidades.
34 Capítulo 3: SOA Fundamentos y Servicio Web Contratos
mensaje
de procesamiento de
lógica de servicio logiccore
servicio Web que actúa como proveedor de servicios
de mensajes de lógica de servicio de núcleo
de procesamiento de
la lógica
mensaje
de procesamiento de
la lógica
de transición de servicio Web a través de papeles de consumo y de proveedores de servicios
básicos logicmessage servicio
de procesamiento
de lógica de
porciones de un servicio Web actuando como consumidor de servicios
Figura 3.6
Tres variaciones de un solo servicio web mostrando las diferentes partes físicas de su
arquitectura que entran en juego, dependiendo del rol que asume en tiempo de ejecución.
Tenga en cuenta el
símbolo en forma de cookie que representa el contrato de servicio encajado entre las capas
de la
lógica de procesamiento de mensajes impulsada por el agente. Este es el mismo símbolo de
círculo con cuerdas que se mostró
anteriormente, pero desde una perspectiva diferente.
ptg3.1 Terminología SOA básica 35
Cuando los servicios se implementan como servicios web, los
documentos de descripción de servicios más comunes son la definición WSDL, la
definición del esquema XML y la definición de la política WS.
Un servicio web generalmente tiene una definición WSDL, que puede vincularse a
múltiples
esquemas XML y definiciones de políticas. Cuando los servicios se implementan como
componentes, el
contrato de servicio técnico se compone de una API específica de tecnología.
Un contrato de servicio puede estar compuesto además por documentos legibles por
humanos, como un
Acuerdo de nivel de servicio (SLA) que describe características,
comportamientos y limitaciones adicionales de calidad de servicio . Como discutimos
en los capítulos de WS-Policy, varios
requisitos relacionados con SLA también se pueden expresar en formato legible por
máquina como políticas. Contrato de
Figura
nivel de servicio (SLA) contrato de servicio web técnico contrato de servicio WSDL WS Policy XML esquema
3.7 Los documentos comunes que componen el contrato de servicio web técnico, más un SLA
legible por humanos . Dentro de la orientación al servicio, el diseño del contrato de
servicio es de suma importancia , tanto que el principio de diseño del contrato de
servicio estandarizado y el proceso de diseño orientado al servicio mencionado
anteriormente se dedican exclusivamente a la creación estandarizada de contratos de
servicio. Tenga en cuenta que debido a que este libro se centra únicamente en los
contratos técnicos de servicios web, los términos "contrato de servicio" y "contrato de
servicio web" se utilizan indistintamente.
Original
T his chapter introduces fundamental concepts relevant to REST service design and
architecture. The objectives of REST are primarily technical in nature and must be
achieved by making clear design decisions to produce a technology architecture that
closely resembles the Web. These design decisions are defined through constraints
that
are associated with architectural properties that represent design goals.
and listen for requests on these capabilities. A consumer invokes a capability by send-
ing the corresponding request message, and the service either rejects the request or
performs the requested task before sending a response message back to the consumer
(Figure 5.1). Exceptions that prevent the task from proceeding are raised back to the
consumer, and the consumer is responsible for taking corrective action.
Stateless {395}
The communication between service consumer (client) and service (server) must be
stateless between requests. This means that each request from a service
consumer should contain all the necessary information for the service to understand
the meaning of the request, and all session state data should then be returned
to the service consumer at the end of each request.
Statelessness is one of the primary influences over service contract design in REST
style architecture. It imposes significant restrictions on the kinds of communication
allowed between services and their consumers in order to achieve its design goals
(Figure 5.2). The application of the Cache {398} and Layered System {404} constraints
helps to compensate for limitations resulting from Stateless {395}
Cache {398}
Response messages from the service to its consumers are explicitly labeled as cacheable or non-
cacheable. This way, the service, the consumer, or one of the intermediary middleware
components can cache the response for reuse in later requests.
The Cache {398} constraint builds upon Client-Server {393} and Stateless {395} with a requirement
that responses are implicitly or explicitly labeled as cacheable or non-cacheable. Requests are
passed through a cache component, which may reuse previous responses to partially or
completely eliminate some interactions over the network (Figure 5.3). This form of elimination can
improve efficiency and scalability, and can further improve user-perceived performance by
reducing the average latency during a series of interactions. However, a common reason for
incorporating caching as a native part of a REST architecture is as a counterbalance to some of the
negative impacts of applying the Stateless {395} constraint.
Code-On-Demand {407}
This optional constraint is primarily intended to allow logic within clients (such as Web browsers) to be updated
independently from server-side logic. Code-On-Demand {407} typically relies on the use of Web-based
technologies, such as Web browser plug-ins, applets, or client-side scripting languages (i.e. JavaScript). Code-On-
Demand {407} can further be applied to services and service consumers. For example, a service can be designed to
dynamically defer portions of logic to service consumer programs. For example, this type of functionality can be
used in support of Stateless {395}, which dictates when session state should be deferred back to the service
consumer. Code-On-Demand {407} can also build upon this by further deferring the processing effort. This
approach may be justifiable when service logic can be executed by the consumer more efficiently or effectively.
Performance
Two fundamental characteristics that distinguish distributed architectures from ones
designed to operate on a single machine are the performance and reliability of
communication. With performance we need to contend with issues such as network
latency and limited network bandwidth. Unreliable networks can also affect
performance by losing, reordering, or delaying packets or messages, and requiring that
they be retried or resent.
We often think of network performance as absolute, but it is driven by a number of
factors, some of which are impacted by architectural decisions. First and foremost is
the issue of what data actually needs to be transferred over the network. Data has to
move if it is needed for processing at a different location from where it is stored.
Therefore, architectures that keep data close to where it is processed naturally
perform better than those that have to move it before it can be processed.
Once it is clear that all data flows are essential, the next question is how those flows
occur and what type of overhead is involved. The fewer messages and round trips over
the network taken to transfer the data and the less overhead that is included in those
messages, the more efficient the transfer will be (Figure 5.5). Protocol overhead can
be incurred as an interaction is started or a connection is established, and as each
message or packet is sent as part of the interaction. Overhead can also be introduced
by transferring irrelevant data that will not be used by its recipient incurred as an
interaction is started or a connection is established, and as each message
or packet is sent as part of the interaction. Overhead can also be introduced by
transferring irrelevant data that will not be used by its recipient.
User perception is also often a performance concern. For example, a large database
query that takes 30 seconds to complete but returns the first page of results in 5
seconds is perceived to perform better than a similar query that returns all results
simultaneously after 30 seconds.
REST can negatively impact performance through its Uniform Contract {400}
constraint.
For example, forcing services and consumers to always share a common technical con-
tract can:
• prevent data exchange optimizations
• result in increased messages or round trips for a given activity to complete
• add redundant overhead to message content
REST can support the performance goal by using caches to keep available data close to
where it is being processed. It can further help by minimizing overhead associated
with setting up complex interactions by keeping each interaction simple and self-
contained (as a request-response pair).
Scalability
Scalability addresses an architecture’s need to support a large number of instances or
concurrent interactions. Four basic approaches for dealing with scalability demands
are identified and can be combined in various ways:
scaling up – increasing the capacity of services, consumers, and network
devices
scaling out – distributing load across services and programs
smoothing out – evening out the number of interactions over peak and non-
peak periods to optimize the infrastructure (thereby reducing the impact of the
peaks to avoid the infrastructure sitting idle at other times)
decoupling the consumption of finite resources – such as memory from
concurrent consumers
Most REST constraints do little to support scaling up or smoothing out the number of
interactions, but the focus is on supporting the scaling out of service instances and on
aligning finite resource consumption to the number of active requests (rather than the
number of concurrent consumers).
REST-style architectures support load balancing across service instances via the
Layered System {404} and Uniform Contract {400} constraints. These constraints allow
services to use off-the-shelf load balancing solutions as the first tier in handling
requests on behalf of a service without changing its technical service contract. This can
be fur-ther simplified through the Stateless {395} constraint, which structures
interactions as request-response pairs that can each be handled by services
independently of other requests. There is no need to keep directing the same service
consumer to the same service instance or to synchronize session state explicitly
between service instances; the session data is contained in each request.
Simplicity
A solution’s distributed architecture is ideally designed to reduce complexity by
separating functionality in such a manner that each unit of functionality is distinct and
easily understood. The simplicity design goal is based on the proper application of the
separation of concerns.
Simplicity is a focus for REST because it impacts how services are defined, discovered,
and eventually used (or reused) and further determines how easily services can be
evolved independently.
modifiability
The requirements for a technology architecture are bound to change over time.
Modifiability represents the ease at which changes can be made to an architecture.
Modifiability in a REST-style architecture is further broken down into the following
areas:
• evolvability – the ability to refactor and redeploy a service, consumer, or middleware
component without impacting other parts of the architecture (even when the upgrade
occurs while applications are running)
• extensibility – the ability to add functionality to the architecture (even while solu-
tions are running)
• customizability – the ability to temporarily modify parts of a solution to perform
special types of tasks
• configurability – the ability to permanently modify parts of an architecture
• reusability – the ability to add new solutions to an architecture that reuse existing
services, middleware, methods, and media types, without modification
Modifiability is particularly important for larger distributed architectures where it is
not possible to redeploy the entire environment every time an architectural improve-
ment is made.
Visibility
Involvement in and understanding of the communication between services and their
consumers allows middleware to monitor and mediate that communication. Within
the context of REST, visibility refers to the ability of parts of an architecture to
monitor and regulate the interaction between other parts of the same architecture.
Most commonly, this translates into establishing middleware-based service agents
that keep track of messages passed between services and consumers.
The focus of these service agents is usually on improving administrative control over
the architecture and optimizing its performance. Typical features provided by utility-
centric service agents include:
• shared caching of responses
• improving scalability through layers that aggregate requests and reduce the direct
impact on services
• improving reliability by ensuring requests always reach a service replica that is
currently available
• supported enforcement of security policies by inspecting and filtering interactions
at network firewalls
The design goal of visibility relates to how much generic information a service agent
can extract from a message without knowing any service-specific contract details. REST
Portability
The ease at which services and solutions can be moved from one platform to another
is represented by the goal of portability. Considerations that should be taken into
account include the level of compatible standardization across environments, the
ability to keep both data and logic grouped, and how portable a given software
program can be. For example, third-party public cloud environments can impose
proprietary architectural characteristics that can inhibit the portability of Web-based
solutions. In contrast, a fragment of JavaScript transferred from a Web server to a
Web browser is highly portable due to the level of platform standardization. An explicit
means by which Code-on-Demand {407} supports this goal is to help standardize
execution environments.
Reliability
Reliability of a distributed architecture is the degree to which its solutions and services
(and underlying infrastructure) are susceptible to failure. The reliability of an
architecture can be improved by avoiding single points of failure, using failover
mechanisms, and relying on monitoring features that can dynamically anticipate and
respond to failure conditions.
Soa
Service-Oriented Design
The service-oriented design phase represents a service delivery lifecycle stage
dedicated to
producing service contracts in support of the well-established “contract-first”
approach
to software development.
The typical starting point for the service-oriented design process is a service candidate
that was produced as a result of completing all required iterations of the service-
oriented
analysis process. Service-oriented design subjects this service candidate to additional
considerations that shape it into a technical service contract in alignment with other
service contracts being produced for the same service inventory.
There is a different service-oriented design process for each of the three common
serv-
ice models (task, entity, and utility). The variations in process steps primarily accom-
modate different priorities and the nature of the logic being expressed by the contract.
This book does not discuss the process of service-oriented design in detail, but there
are
references to some of the considerations raised by the “contract-first” emphasis of
this
process.
Web Service
A Web service is a body of solution logic that provides a physically decoupled technical
contract consisting of a WSDL definition and one or more XML Schema and/or WS-
Policy definitions. As we will explore in this book, these documents can exist in one
physical file or be spread across multiple files and still be part of one service contract.
Spreading them out makes them reusable across multiple contracts.
The Web service contract exposes public capabilities as operations, establishing a tech-
nical interface comparable to a traditional application programming interface (API) but
through the use of service adapter products. When custom-developed, Web service
logic
is typically based on modern component technologies, such as Java and .NET. In this
case, the components are further qualified as core service logic.
Service Contract
A service contract is comprised of one or more published documents that express meta
information about a service. The fundamental part of a service contract consists of the
documents that express its technical interface. These form the technical service
contract,
which essentially establishes an API into the functionality offered by the service via its
capabilities.
34 Chapter 3: SOA Fundamentals and Web Service Contracts
message
processing
logiccore service logic
Web service acting as a service provider
core service logic message
processing
logic
message
processing
logic
Web service transitioning through service consumer and provider roles
core service logicmessage
processing
logic
Portions of a Web service acting as a service consumer
Figure 3.6
Three variations of a single Web service showing the different physical parts of its archi-
tecture that come into play, depending on the role it assumes at runtime. Note the cookie-
shaped symbol that represents the service contract wedged in between layers of
agent-driven message processing logic. This is the same chorded circle symbol shown
earlier but from a different perspective.