The following article assumes the developer knows Java* & Maven. Download the seed project to get started with plugins.
Here is the example plugin. You can download it from github.
<!-- Place this tag where you want the button to render. --> <a class="github-button" href="https://github.com/metamug/plugin-example/fork" data-icon="octicon-repo-forked" data-size="large" aria-label="Fork Metamug Plugin Example on GitHub">Fork</a> <!-- Place this tag in your head or just before your close body tag. --> <script async="" defer="" src="https://buttons.github.io/buttons.js"></script>
Plugins allow the developer to write custom business logic for their API using Java. Code Execution capabilities are provided via SDK to pre-process request, post-process sql results or run a business logic.
Because there will be cases where direct sql result to JSON would not be sufficient.
The user is required to upload a compressed .zip of a Maven project folder. The zip can be uploaded by click on New Project button in the Plugins section of the console.
No other format except zip is supported for the project upload. Please do not upload .tar.gz, .rar or any other format.
The project should contain the following
- One or more classes implementing one of the Processable interfaces explained further in this article.
- One or more classes whose object is to be returned in the HTTP response. If custom objects are being returned.
The details of uploaded projects and information of processable classes is shown in the console
The following dependency must be provided in the pom.xml of the Maven project
Metamug provides following two Java interfaces
The classes implementing either of these interfaces must be public and will have to Override the
process() method. The code inside the process method gets executed and an
Object is returned. The returned object is converted to XML or JSON as specified by the HTTP request header and is returned in the HTTP response.
<!-- Place this tag where you want the button to render. --> <a class="github-button" href="https://github.com/metamug" data-size="large" aria-label="Follow @metamug on GitHub">Follow @metamug</a> <!-- Place this tag where you want the button to render. --> <a class="github-button" href="https://github.com/metamug/mtg-api" data-size="large" data-show-count="true" aria-label="Star metamug/mtg-api on GitHub">Star</a> <!-- Place this tag in your head or just before your close body tag. --> <script async="" defer="" src="https://buttons.github.io/buttons.js"></script>
Two types of plugins can be created for Metamug
- Request processors - Incoming HTTP requests can be directly processed upon.
- SQL result processors - The result set received by making SQL query to the database can be processed upon.
RequestProcessable interface can be implemented to process HTTP request. The
process() method provides access to the request parameters, the DataSource object and the request headers. The class implementing the interface should be public.
DataSource object is used to obtain the database connection. The connection is given to the database of the backend in which the Maven project is uploaded. The connection must be closed after the database operation is done.
Execute tag is used for invoking the RequestProcessable classes. The value of classname attribute has to be the full name of a RequestProcessable class (including package name) inside an uploaded maven project. When the HTTP request is made to the resource, the
process() method inside the corresponding class will be executed. The HTTP request parameters will automatically be mapped inside the
Map<String,String> of the
outputattribute hints the api to print the response of the
This interface must be implemented to process SQL results. The
process() method provides
columnNames to iterate through records and look up column names. The
rowCount gives the number of records in the resultMap. This method is provided to override the XML/JSON output for SQL queries. This helps the user to customize the HTTP response body. The Content-Type header in this case will be text/plain and Content-Length will be the length of the output string.
The result map obtained inside the
process() method of the ResultProcessable class can be used to obtain values from the database which can be used for further processing.
The result received by executing the SQL query can be processed upon by the developer using the ResultProcessable interface. The attribute "classname" is available for the
<Sql> element which is used for pointing to the ResultProcessable class. Let us consider the following resource file
In the above case, the given SQL will be executed when a GET request is made on the urls resource. The result obtained from the database on the execution of the SQL query will be handled by the com.mycompany.plugin.ResultHandler class (included in an uploaded maven project) which implements the ResultProcessable interface.
* Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.
Execute Output Processing
process() method has return type as
Response. Response payload is designed to handle following 3 types.
- Pojo with Annotations
- Inputstream or ByteBuffer
A simple Java string returned by the
process() method can be obtained directly as it is in the HTTP response.
POJO with annotation
The class of the object returned by the
process() method should be annotated with JAXB annotations. At a minimum, the class has to be annotated with
@XmlRootElement to automatically produce XML/JSON response depending on the Accept Header.
This is the minimal configuration required to configure serialization of the object to json/xml. You can find the whole list of annotations on oracle's doc page.
Take a look at this example for more on returning objects.
InputStream object is set as the payload of the
Response. This is useful for downloading a file. Inside the
process method, file can be accessed from the desired location and converted to InputStream object.
Alternatively, in certain cases we may prefer to peform some operations on the file input stream before we send it for download. In such a case, ByteBuffer can be returned after operating on the byte array obtained from the inputstream.
Event Handlers are invoked implicitly. They need not be declared from resource xml. However, plugins must include implementation of these handlers.
A request can be directed to the POST method of a request. As Upload event handler should be executed before the request is forwarded to the resource. So the handler can pass the
Response to the resource xml.
When Upload is performed, the class implemented with the following interface is invoked. The uploaded file can be accessed from the event object also you will need to keep the param of the file object as
Here a user must return a
Response Object which can be made available to the resource. If the resource is authenticated then it is mandatory to pass the authorization token else the upload will not work.
The upload Listener is saved with implicit id
_upload. It can be accessed in the resource using the MPath
To access the uploaded file, we will write another execute tag as follows in the same POST request.
By default, file upload is disabled in console. To enable file upload, the default file uploader plugin must be uploaded in plugins.
Update the plugin to the latest dependency. You can download the default File Uploader plugin from here.