Development Basics
Workflow
Overall a new Native Module can be achieved in five basic steps:
-
Create a new module with the needed classes via Dashboard
-
Download the Native Module SDK / Check out the Native Module code from the Git repository (depending on how you created the module)
-
Import the SDK into your development environment
-
Insert the logic to be executed in the backend
-
Upload the modified module / push the changes to the Git repository (depending on how you created the module)
This guide assumes that the used IDE is Eclipse, although it should be possible to operate the following instructions with other IDEs.
Creating a new module
Details about how to create a new module via Dashboard can be found here.
Download / Check out
Depending on how you created your Native Module, you can either download it or check it out from a Git repository.
Insert the backend logic
You can insert your own logic into modules using hook classes.
Upload the module
Other important facts
As the above guide to a working Native Module, there are some further technical aspects you should know about.
Package structure
The package com.apiomat.nativemodules includes all Java classes. On the lowest level there are interfaces, annotations and utility classes that are needed for execution. The package com.apiomat.nativemodule.basics contains the classes User and Role which exist in each module. User represents a user of an app and Role describes a role that a User can take.
There exists a package on the same level as basics which holds non-generic classes that are specific for this module; default files have already been generated for the previousely created classes. They will be focused on in the following chapter.
ApiOmat generates a bunch of packages and classes to be adjusted by the user, it is still possible to benefit from common architecture patterns, just like ordinary desktop development. Therefore you can put additional packages and classes into the package com.apiomat.nativemodule and call them from within the hook methods. After uploading the module, the functionality can be accessed by apiOmat.
Module logo
A file called "logo.png" can be placed inside the "src" directory if the module should obtain its own module image. It must be ensured that it contains a transparent background and measures 80x80px.
Module description
Optionally, a module description can be specified which will be displayed below the module name in the module market of the Dashboard. Therefore an annotiation is added to the module class as follows:
@Module
(description =
"my description"
)
The field "description" can be fillled with an arbitrary text.
SDK-Properties
This properties file sdk.properties holds all data that is necessary to automatically up- or download an updated SDK containing changes to the class structure to or from apiOmat .
Initially the following values have to be adjusted:
-
password - the app admin's password
-
curl.path - cURL binary path
-
merge - "true", if the download should not only inlcude generated classes and utility classes but also customized and self-made classes. (e.g. hooks, REST Endpoints, ..)
-
update - "true", if local changes to model classes should be recognized by apiOmat and thus be reflected in the class structure
- "overwrite", if an attribute has been modified or deleted locally and these changes should be repeated to the server
- "false", for none of the above (or just comment out the update setting)
Libraries
The folder lib contains all libraries that are necessary for this project. They include libraries like Kryo for serialization and other
apiOmat
modules, as well as the currently developed module uses other modules (e.g. the SAML module for SSO authentication). The latter have to be added to the build Path as described above.
Other libraries that are needed by the module can naturally be added here as well. It should be noted, that libraries that are already included in YAMBAS (e.g. Apache HTTP Client) must have the same version number as the corresponding YAMBAS libraries!
A list of all libraries that YAMBAS uses can be retrieved through calling <BasisURL>/yambas/rest with authentication credentials of the Super Admin, for example:
curl http:
//localhost:8080/yambas/rest -u apinaut@apiomat.com:secret
Main class
First of all there is a module main class whith the same name as the module.
Since the module main class can internally be instantiated multiple times, it should be noted that when using the key word "static". Static variables will share their values with every app that uses the respective module. If App A changes a static variable of a module class, this new value will be visible and editable from App B, too.
This behaviour is not intended in most cases and can be avoided by storing values inside a map with the respective app names as keys. Instead of
static
Connection con;
you could use
static
Map<String, Connection> con;
The main module initially contains the following methods:
public
void
onDeploy( )
public
void
onUndeploy( )
public
void
setAppConfigProxy( IApplicationConfigProxy appConfigProxy)
public
void
onConfigChanged( String appName, String configKey , String system)
onDeploy is called each time the module is uploaded using the SDK upload or if its status is manually changed to "DEPLOYED". onUndeploy will be executed if the module status was set to "UNDEPLOYED".
setAppConfigProxy is executed immediately before onDeploy. Its parameter holds an object of the type IApplicationConfigProxy which allows access to the module configuration with its only method getConfigValue( String key, String appName, String usedSystem). An example call may look like:
<ModuleName>.APP_CONFIG_PROXY.getConfigValue( <ModuleName>.<ConfigName>, appName, system );
Module configurations are specified each time the module is added to an app using the Dashboard as shown in the example of the Evelange module:
There also exists a onConfigChanged method since it is possible for users to change the module configuration over time. This method is called on any change to the current configuration and receives the app name as well as the changed key through its parameter list. This means that onConfigChange is called once for every changed configuration parameter.
It naturally is possible to define configuration parameters for your own module. This is done by defining a static String variable and adding the NativeModuleConfig annotation:
@NativeModuleConfig
( datatype = Type.TEXT, example =
"http://www.mywebsite.com/api"
, title =
"URL"
,
info =
"URL endpoint my website"
,
key =
"url"
, order =
1
)
public
static
String URL =
"mymodule_url"
;
NativeModuleConfig provides several data types, an example value, a title and a description for a specific configuration parameter. The display order on screen shown above of several parameters can be modified by specifying the "order" field.
It is advised to follow the naming convention for string variables in such a manner as it uses the lowercase module name as a prefix which is followed by an underscore and an acronym of the variable. As soon as the configuration parameters are added to the module main class and the SDK has been uploaded, the parameter can be displaid by removing the module from the app and adding it again.
User-defined classes
Each meta model that is created through the Dashboard causes the generation of a new Java class which possesses the same attributes with associated access methods and it is annotated with "@Model". This generated class cannot be changed although changes to the data model can be done through the Dashboard and downloaded afterwards using the SDK download. Unchanged files will be overwritten while doing so. However, it is possible to add new atributes directly in the source code of a user-defined class. They will be added in apiOmat automatically as soon as the updated source code is uploaded. The SDK can be downloaded afterwards if it isn't required to define Getters, Setters and methods for serialization oneself since existing classes will be replaced by generated ones.
In order for changes in these classes to take effect after uploading, the update flag must be set with "update = true". If existing attributes are to be deleted or modified as well, the flag "update=overwrite" must be set. If you don't want any of this, set "update=false" or comment it out.
References can be annotated with "@EmbeddedDocument" to mark them as Embedded Documents .
@EmbeddedDocument
private
Address address =
null
;
Create an own REST interface
It is possible to specify a class that should receive REST requests in the method getSpecificRestResource(...) of the module class. Thus, it is possible to provide an entirely custom-tailored REST interface e.g. to implement OAuth callbacks. Please see this separate article.
Authentication checks
Helper methods provide several possibilities to check authentication programmatically. See more at the separate article.