:toc: macro
toc::[]

= Service Layer

The service layer is responsible for exposing functionality made available by the link:guide-logic-layer[logical layer] to external consumers over a network via xref:protocol[technical protocols].

== Types of Services

Before you start creating your services you should consider some general design aspects:

* Do you want to create a https://en.wikipedia.org/wiki/Remote_procedure_call[RPC] service?
* Or is your problem better addressed by messaging or eventing?
* Who will consume your service? 
** Do you have one or multiple consumers?
** Do web-browsers have to use your service?
** Will apps from other vendors or parties have to consume your service that you can not influence if the service may have to change or be extended?

For RPC a common choice is link:guide-rest[REST] but there are also interesting alternatives like https://grpc.io/[gRPC]. We also have a guide for link:guide-soap[SOAP] but this technology should rather be considered as legacy and is not recommended for new services.

When it comes to messaging in Java the typical answer will be link:guide-jms[JMS]. However, a very promising alternative is link:guide-kafka[Kafka].

== Versioning
For RPC services consumed by other applications we use versioning to prevent incompatibilities between applications when deploying updates. This is done by the following conventions:

* We define a version number and prefix it with `v` (e.g. `v1`).
* If we support previous versions we use that version numbers as part of the Java package defining the service API (e.g. `com.foo.application.component.service.api.v1`)
* We use the version number as part of the service name in the remote URL (e.g. `https://application.foo.com/services/rest/component/v1/resource`)
* Whenever breaking changes are made to the API, create a separate version of the service and increment the version (e.g. `v1` -> `v2`) . The implementations of the different versions of the service contain compatibility code and delegate to the same unversioned use-case of the logic layer whenever possible.
* For maintenance and simplicity, avoid keeping more than one previous version.

== Interoperability
For services that are consumed by clients with different technology, _interoperability_ is required. This is addressed by selecting the right protocol, following protocol-specific best practices and following our considerations especially _simplicity_.

== Service Considerations
The term _service_ is quite generic and therefore easily misunderstood. It is a unit exposing coherent functionality via a well-defined interface over a network. For the design of a service, we consider the following aspects:

* *self-contained* +
The entire API of the service shall be self-contained and have no dependencies on other parts of the application (other services, implementations, etc.).
* *idempotence* +
E.g. creation of the same master-data entity has no effect (no error)
* *loosely coupled* +
Service consumers have minimum knowledge and dependencies on the service provider.
* *normalized* +
Complete, no redundancy, minimal
* *coarse-grained* +
Service provides rather large operations (save entire entity or set of entities rather than individual attributes)
* *atomic* +
Process individual entities (for processing large sets of data, use a link:guide-batch-layer[batch] instead of a service)
* *simplicity* +
Avoid polymorphism, RPC methods with unique name per signature and no overloading, avoid attachments (consider separate download service), etc.

== Security
Your services are the major entry point to your application. Hence, security considerations are important here.

See link:guide-rest#security[REST Security].
