: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].