Development Basics
This page is an introduction to the basics of developing services with ApiOmat. It consists of a simple introduction to the development workflow and a brief overview of the relevant service assets. Links to further topics will help you dive deeper into service development.
Contents :
Workflow
In a nutshell, you can create a new service in the following steps:
-
Model your service via the ApiOmat Dashboard.
-
Download your service and retrieve project assets.
-
Develop your service and deploy the newly created sources to a repository.
-
Start your service.
-
Retrieve existing logic & code-first approach.
These steps are described in detail in the Development cycle guide.
About the service assets
As the list above guides you to a working service, there are some further technical aspects you should know about.
Package structure
A generated service will have the following architecture (example service "MyService"):
The generated base package is "com.apiomat.microservice.{serviceName}", it contains:
-
The Spring Boot application main class, named after the service with "Application" appended (e.g. MyServiceApplication.java). It contains annotations to start the Spring Boot application and enable Feign:
MyServiceApplication.java@SpringBootApplication
@EnableFeignClients
public
class
MyServiceApplication
extends
SpringBootServletInitializer
-
The main Spring-related configuration, "{serviceName}Configuration.java", that contains the configuration and initialization of all the beans required for your service logic.
-
The "config" package which contains:
-
A SwaggerDocumentationConfig.java class, which contains specific configuration to generate an OpenAPI specification. This is done for all REST endpoints annotated with the @ApiXXX swagger annotations from the springfox-swagger2 library. The OpenAPI specification is available by default at http://localhost:8090/{lowerCaseServiceName}/v2/api-docs and is accessed by the Explorer service to display the API documentation UI.
-
A "{serviceName}ConfigDefinition.java" class that contains the specific ApiOmat application configuration definition of your service. See Configuration Parameters.
-
A "{serviceName}CorsConfiguration.java" class that contains the CORS configuration for your service. See CORS configuration.
-
-
The "controller" package which contains the following for each class:
-
An API interface "I{className}Api.java" that describes API endpoints.
-
An API implementation "{className}ApiController.java" to call internal service logic.
-
-
The "model" package which contains the following for each class:
-
A POJO "{className}.java" that holds the class's attributes.
-
An enum list of reference attributes "{className}RefAttributes.java", used when querying the data model's reference endpoints.
-
An enum list of static data attributes name "{className}StaticDataAttributes.java", used when querying the data model's static data endpoints.
-
-
The "service" package which contains the following for each class :
-
A Feign client "{className}ApiClient.java" that calls the corresponding Yambas endpoints when a data model's CRUD operations are executed.
-
An API abstract service "Abstract{className}ApiService.java" that provides default implementations of service methods.
-
An API service implementation "{className}ApiServiceImpl.java" that extends the abstract implementation, where the developer can make their own implementations of service methods by overriding the default abstract provided ones.
-
The resources folder contains:
-
The "application.yml" Spring configuration file, with specific values described below in the Service Configuration - Spring related configuration section.
-
A "logback.xml" logging configuration file, see Logging and Debugging for details on this
-
You can place your own logo for the service here. For details see section Add logo for marketplace
This was only a quick overview of the classes that are generated within your Spring Boot service project. Please go to the Service architecture guide for more details on the global logic and architecture.
Maven dependencies
In this section, we'll list the dependencies that are defined in the pom.xml of your generated service and explain what each of them is for. Links to related documentation will be provided when relevant.
Parent
Each generated service is a child of our spring-microservice-base parent project . It provides the general dependencies and global dependency management used by every ApiOmat service. The goal of this parent project is to manage the versions used in the ApiOmat ecosystem for compliance purposes.
Note that the current version of spring-microservice-base contains dependencies as well as dependency management. Future versions of spring-microservice-base will correct this behavior and only provide dependency management.
ApiOmat libraries
Some dependencies are custom artifacts we provide to make it easier to integrate services within the ApiOmat ecosystem:
Name |
Description |
brewer-base |
Contains the basic POJOs and interfaces used in all ApiOmat microservices, and provides the global logic applied to your microservice's service classes. This library is the service equivalent of the nativemodule-base library, which you may be familiar with if you have worked with native modules. Most of the features provided by the brewer-base library are described in the service architecture documentation . |
apiomat-service-config-starter |
Provides features to enhance the usage of ApiOmat configuration parameters in Spring Boot microservices. Features provided by this library, and the apiomat-service-config library, are described in the Configuration Parameters documentation . |
Others
Name |
Description |
logback-gelf |
Provides a log appender implementation for Graylog. The appender is defined in your logback.xml file. More information about Graylog can be found in our Graylog documentation. |
Maven plugins
The pom.xml of your generated service will have the following Maven plugins:
Name |
Description |
spring-boot-maven-plugin |
Provides several Maven goals to work with a Spring Boot application. See usage documentation. |
dockerfile-maven-plugin |
Provides features to create a docker image of your service. See the plugin's GitHub page. |
license-maven-plugin |
Generate license information about used dependencies. |
maven-war-plugin |
Plugin to package your service as a Web Application Resource (WAR). |
maven-source-plugin |
Plugin to package the sources of your application. The sources are deployed to Innkeeper so files can be merged. Also used in code-first approach to update your service's metadata. |
brewer-maven-plugin |
Our custom maven plugin to support service development. See the plugin's public documentation. |
Application main class
The entry point of your service is its application class {ServiceName}Application.java. It contains a main method and is annotated with @SpringBootApplication which is explained in more detail in the Spring Boot documentation .
An important feature to be aware of when using @SpringBootAnnotation is the @ComponentScan annotation. By default, a bean will be created and added to your service's application context for all classes annotated with @Component (or its child annotations such as @Service or @Controller) from the package where your @SpringBootAnnotation annotated class is located, and from all sub package s.
With the default behaviour of @ComponentScan , putting a class annotated with @SpringBootApplication in a top level package may result in a lot of unwanted components being added to your application context. For example, an annotation on the "com" package level will add all components from "com.*" to your application context, including dependency classes that are annotated with @Component and located in the "com.*" package of their dependency, which is definitely not wanted behavior. Try to keep your package names as specific to your application as possible.
Service Configuration
Configuration via properties is a key part of Spring. Typically, you can define your application configuration in a YAML or properties file (e.g. in your generated service, there will be an application.yml file) .
ApiOmat application configuration
It is possible to define ApiOmat application- and system-related configurations for your service, where values can be dynamically accessed and changed within your service logic at runtime. To dive deeper into this topic, please refer to Configuration Parameters .
Service discovery, health checks and load balancing
In a Cloud context, services need to communicate with each other, so they need to be able to find each other. The principle of service discovery is that a single discovery client holds information about all services in the Cloud. When a service starts up, it registers itself to the discovery client, with some additional configuration if necessary. When a service wants to communicate with another service, it can retrieve the address from the discovery client.
For service discovery, we are using the Consul discovery client from HashiCorp. An additional useful feature of Consul is health checking: Each service registers itself with an endpoint for health checks, which is queried by Consul to assert the service's healthiness. Please refer to Service health checks for further information.
The picture below describes our discovery use case with the different features provided by Consul:
Another useful principle when working with services is load balancing. Imagine that you start two instances of the same services in order to scale your application - how can you make sure that the workload is efficiently distributed between both instances?
Load balancing will solve this for you. We use the client side load balancer Ribbon, with a default implementation from Spring Cloud. By default, Feign also supports load balancing using Ribbon.
Each Ribbon client can be configured to include a list of service instances that could be retrieved from the discovery client. The Ribbon implementation includes some rules which are applied in order to distribute the workload over multiple instances. For more information on load balancing with Ribbon, you can have a look at the Spring Cloud documentation .
Logging and Debugging
To learn about the logging and debugging features, please refer to Service Logging and Debugging .
Data model classes
When you generate your service, a corresponding Java class will be created for each of your service's classes. This class will contain any attributes that you defined in the Dashboard. As mentioned above, these data model classes will be placed in the package com.apiomat.microservice.<servicename>.model.
Attribute Annotations
There are several attribute annotations for various attribute-specific information. They are applied automatically during service generation, and can be added manually when creating new attributes by editing the source code.
EmbeddedObject
References can be annotated
with EmbeddedObject to mark them as
embedded objects
.
For example:
@com
.apiomat.service.base.model.EmbeddedObject
private
Address address =
null
;
Mandatory
Attributes can be annotated
with Mandatory to mark them as mandatory attributes.
For example:
@com
.apiomat.service.base.model.Mandatory
private
String mandatoryStr =
null
;
Next steps
-
If you are now familiar with the different concepts of Service development in ApiOmat, but you want to practice before creating your own, please follow our Introduction tutorial .
-
You now feel ready to create your own service? Please have a look at the services we provide in the ApiOmat cloud, as they may be helpful for your future development.