Showing posts with label RESTful. Show all posts
Showing posts with label RESTful. Show all posts

Tuesday, February 9, 2016

ADF Spotlight: REST in ADF 12.2.1

In the recent ADF Spotlight Webconference I have given a presentation and live demo on some of the new REST features in ADF 12.2.1. The recording (in german) is on youtube: https://www.youtube.com/watch?v=SmrINlqVNPs

The new REST features (to create REST resources) are implemented on top of Application Module (WebServices > REST). Here you can choose a Root View Instance, assign it to a release version and further configure the defined REST resource in a new Overview Editor.

Following summarizes some of the new REST features in ADF:

Resource Versioning

Versioning is the first thing need to be configured before you can start creating REST resources. It is supported at the level of the adf-config.xml file. Here you can define different versions. Each version can be configured as  active, deprecated or desupported. To keep things simple I recommend to use same name for internal and release name.


Versions marked as desupported will reply with HTTP 500  and corresponding message. They will not serve any REST Data.


Versions marked as deprecated will work. If you invoke the URL for v2 metadata you will get information that there is a successor-version:


It implements the HATEOAS principle and therefore is very developer friendly.

Read, Create, Update, Delete Out-of-the-box

By default all REST HTTP Methods are exposed on a resource. GET for read, POST for Create, DELETE for Delete. To partially update a resource (only some attributes e.g.)  the PATCH method is exposed.  For PUT you need to provide all attributes (It will do kind of a replace).

Important: When working with the REST API it is important to set the Content-Type to application/vnd.oracle.adf.description+json otherwise there will be the following exception:

oracle.adf.internal.model.rest.core.exception.CannotParseContentException: The PayloadParser could not be found in the ResourceProcessingContext.

See the following Postman PATCH sample:

Pagination for collections by default

Having a REST collection ADF automatically exposes parameters for pagination. Just append limit und offset as URL parameters and your good to go. see next pic to get a feeling how the parameters affect the response:

Children and LOVs as sub-resource

This is also a pretty great feature. 

By a simple configuration child view object instance will be exposed a sub-resources.



Configured LOVs on specific attributes will by default be exposed as sub-resources too. See example in postman:

Attribute Shaping

By default all attributes of a View Object will be exposed in the REST resource. If you want to expose only a subset of the attributes you can define "Service Shapes" on the View Object

and use those to customize the REST resource (Tab: Attributes)


Security

Securing ADF REST Resources is quite powerful. It works just like with Pages / Taskflow Permission. You just need to run the ADF Security Wizard on the RESTWebService project.

More features

Canonical Link

The canonical link is used to link to a resource that represents the full representation (of REST resource). This can be an "internal" defined View Object or an external (by pointing to the corresponding) ADF Connection.

See details in the Dev Guide: How to expose canonical Resources

RowFinder Key

With RowFinder configuration it is possible to change the URL of a resource from e.g. /employees/100 to /employees/SKING

Expose Custom Methods in the ADF REST Resource

To be evaluated ;) The ADF Documentation is not very clear about that topic.


--
Sample Code: https://github.com/enpit/enpit.sample.adf1221.restsandbox

Further information




Tuesday, November 3, 2015

Consume JSON based ADF REST Services in ADF 12.2.1 (with REST DataControl)

In ADF 12.2.1 the capabilities for handling with REST services has been greatly improved. You can now expose ADF BC (ViewObjects) as  REST service in JSON format.  On the other hand there are improvements in the REST DataControl.

In this blog post I am going to show how to consume this REST Service and create a basic ADF Table.

So here is a basic REST Service for employees


REST DataControl with JSON Support

From „New Gallery“ open the following wizard


The create web service data control wizard launches. Choose REST option.


Next you can decide whether you consume a REST service, that has been exposed through ADF BC Application Module or a generic REST service. The difference here is that the ADF based REST service exposes additional meta data that describes the structure and types of the return JSON structure. This makes it possible to automatically get a type-aware DataControl on REST/JSON service which is generically not the case. See next screenshot to get a feel of the feature of an ADF REST Service and this particular describe feature.



So lets add an ADF REST Connection


Important note: Do include the version name and resource name, but do not include any URL parameters.

Next it is possible to choose from Security Policies

Since in this example we do not use any security just skip this page.

Next you can choose to add all resources or specific one. in this case I have only one resource exposed


Click Next and Finish.

=> The DataControl will be created. Every attribute type is correctly derived from the rest metadata (ADF REST service specific).



(Interesting to note, that EmployeeId is not marked as the primary key. Although it is in the ADF BC ViewObject definition from which the service has been previously created. Well it is because of the REST nature of this Collection. Resources typically must not match every attribute of an ADF ViewObject. It could be a subset. Therefore the canonical attribute represents the primary key which is typically the URL to the canonical resource. In our case the canonical resource is the resource itself :))

Next steps are as easy as with any other DataControl. Just create an ADF table via drag and drop

Run the page.


Table is displayed. Filtering works BTW too. Nice.

Since we are consuming an ADF REST Service lets see if we can update a record. Therefore Drag and Drop the „Commit“ Operation from the Data Control. Create a button and name it „Save changes“. For a simple testcase we change the salary from initially 10000 to 5000. Press „Save changes"


Looking into the database you will notice the change


Pretty cool.

Issues

Removing the Filter results in an NullPointerException. Hhhm that is disappointing. Looks like nobody has tested this so far ;).


Refreshing the page the table keeps empty (Not data to display). Looks like a bug. It would not surprise me. Anyone feel free to file a SR to Oracle.

Sample applications

Provider: enpit.sample.adf1221.restprovider.zip
Consumer: enpit.sample.adf1221.restconsumer.zip

Further information

ADF 12.2.1 Developers Guide:

16.3.1 How to Expose Canonical Resources in the ADF REST Resource
22 Consuming RESTful Web Services Using the ADF REST Framework

Sunday, October 4, 2015

Setting up a Mobile Backend in Oracle Mobile Cloud Service (MCS)

A mobile app typically needs to access some services from the outer world. That might be some generic services for user management, storage/database, notifications, etc. (so called Platform APIs) or some business domain/app specific APIs - called Custom APIs.



In Oracle Mobile Cloud Service all services are exposed through a mobile backend. The mobile backend can be versioned and is associated with a User Realm. To access services from a mobile backend the app needs to know the unique ‚mobile-backend-id‘ and the app must be registered with the mobile backend. That registration is done in the settings of the mobile backend from within the MCS UI. So in short: the mobile backend acts as a secure container for APIs.

Creating and Configuring a Mobile Backend

Step 1: (Prerequisite) Setup User Realm with Users And Roles. Checkout the Getting Started on User Management or  the MCS Video on "Defining Users and Properties in Realms". It is pretty straight forward. The focus in this post is on mobile backend.

Step 2: In MCS goto „Development“ > Mobile Backends
Click „New Mobile Backend“ to open the wizard

Enter a name for your backend and click „Create“.
Next you will be navigated to the „Settings“-Tab of the newly created Backend.


In the settings the information is displayed which is needed in order to connect an app through this mobile backend:  Base URL, Backend ID, Anonymous Key (for anonymous access) and Application Key. For each registered application a new application id is generated.

Step 3: Associated Mobile Backend with a user realm
By default every newly created mobile backend is associated with the Default Realm. To change this open your mobile backend in MCS and goto „Users“ and Choose „Change User Realm"


Step 4: Add Custom APIs
Open your mobile backend and goto APIs

Now you can select an existing custom API or create a new API on the fly.
„Select APIs“ takes you to the API Catalog to select an API


Click on the „+“ to add the API to your mobile backend. In this sample the HR API will be associated with my HR Mobile Backend.

That’s all for a basic mobile backend.

Test the mobile backend

(1) Right from within MCS it is possible to make a first test on the API


(2) Because everything in MCS mobile backend is exposed as REST service you can simply use cURL for quick tests, e.g.

$ curl -i -u username:password -H „oracle-mobile-backend-id: c3a65860-f3a8-XYZ2-af44-061b8dc6143c" -H "Content-Type: application/json;" --request GET http://:7201/mobile/custom/hr/employees

HTTP/1.1 200 OK
Date: Fri, 24 Jul 2015 16:45:53 GMT
Transfer-Encoding: chunked
Content-Type: application/json
Oracle-Mobile-Test: Response Generated from RAML
oracle-mobile-runtime-version: 15.3.3-201507070814
X-ORACLE-DMS-ECID: 155856d5d1d09189:53b26884:14ebd8aed21:-8000-000000000000d67e
X-Powered-By: Servlet/2.5 JSP/2.1
Set-Cookie: JSESSIONID=BnjQVyrB6vhWKQhsR1pYsrkbQnQXwR2ZRD5NJ5QlTWNKPhQ4hXjn!15090744; path=/; HttpOnly


Connect to the mobile backend

Next you can go in your mobile app development environment to code against the mobile backend. For iOS and Android there are MCS SKDs available. You can download them right from the MCS Portal. Check out the user guide how to connect with the specific SDKs (see links below).

Interesting to note: For Oracle MAF no special MCS SDK is available. But stay tuned - there will be some MAF MCS Utilities available shortly with support for MCS. Further more there is an MCS SDK for Xamarin which is great news. Checkout the Xamarin Oracle Mobile Cloud Service SDK 1.0. It shows the MCS might have a bright future for enterprise mobile backends. I hope to see it!

What's next? Design and Implementation of Custom APIs for the "mobile service developer" and consuming the Services for the "mobile app developer".

Further information




Saturday, June 7, 2014

Create RESTful services on top of ADF Business Components


Introduction

Creating SOAP Services on top of ADF Model is for a long time quite easy and convenient. In JDeveloper: Open an ApplicationModule goto WebService Tab and create a Service Interface by exposing some given ViewObject Instances or custom Service methods. See http://www.oracle.com/technetwork/issue-archive/2012/12-sep/o52adf-1735897.html (Consume Early, Consume Often) for more details and great explanation or take a look in the official Oracle documentation http://docs.oracle.com/cd/E23943_01/web.1111/b31974/bcextservices.htm#CJAJGIEB (11 Integrating Service-Enabled Application Modules)

Options to create RESTful Services on top ob ADF BC Model

Creating a RESTful Service Fassade on top of existing ADF Business Components Model is not that straightforward. From different „announcements" we know that Oracle plans to generate RESTful Services ADF BC SDO (Service Data Object) in the future. But for now we need a custom solution.

Exploring various possibilities I came up with the following


Note that the Service Facade is optional but recommended in terms of „separation of concerns", „service virtualization", „clean code", etc. Watch the youtube ADF Insider Essentials for the detailed explanation of the Service Facade Pattern.

Going from top to bottom in the diagram we have the following options
a) ADF BC -> SDO Service Interface -> WebService  -> SOAP 
b) ADF BC -> SDO Service Interface -> Inject EJB in REST-Resource -> REST
c) ADF BC -> Use AM Instance programmatically in REST-Resource ->REST
d) this one is planned for some 12.1.3+ release (and in future will be the default option to expose RESTful Services for a given ADF BC Model).

In this post I am covering case b. I did not find a sample on the web yet. So I give it a try cause it looks like THE pragmatic approach so far.

Howto

For the example I am using JDeveloper 12.1.2 and the corresponding Runtim ADF 12.1.2. In order to understand the next steps I assume you know the basics of ADF and JDeveloper.

1. Create ADF BC SDO SOAP Service for an Application Module:
Open the AM in „Overview", goto "Web Service" Tab. Now open the dialog to create the service interface.

Choose the desired VO-Instances and apply you changes.

JDeveloper should generate some files now. If you take a look in the *ServiceImpl.java Class you will notice that  it is exposed as Stateless Session EJB. This is great!

Because from now on you can use the EJB in a REST-Resource to expose it as RESTful-Service. That's what we are planning to do next.

But before this step test your generated (SOAP-based) service first: Make sure you do not ran into the „StackOverflowException" because the SDO Service will try to traverse the ViewLinks recursively. So the following exception might be the one you will run into.

To fix this, open the corresponding ViewLink and uncheck the property „Generate Property in SDO"


2.  Next: Create a new Project for the RESTful Service
Use the right project template from the NEW-Wizard

Open the NEW-Wizard again and create a RESTful service from new

Deselect the Checkbox in front of GET-Method. We are going to do that later in Sourcecode.

Finish. => This should generate a Java class and configure the project with the Jersey Library.
For the sample to complete the project needs on more adjustment in the project properties. 
- One more Library (Context and Dependency Injection CDI)
and a dependency to the Model-Project because the RESTfulWebService project need access to the application module.

Thats all for the project setup.

3. Add some classes, annotations and the methods you want to expose

import javax.ejb.EJB;

import javax.inject.Singleton;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import oracle.jbo.service.errors.ServiceException;

@Singleton
@Path("api")
public class HrRESTResource {
   
    @EJB
    HRAppModuleService serviceBean;
   
    public HrRESTResource() {
    }
   
    /**
     * getEmployeesView1: generated method. Do not modify.
     */
    @GET
    @Path("emp/{empId}")
    @Produces(value = { "application/json", "application/xml" })
    public EmpResult getEmployeesView1(@PathParam("empId") Integer employeeId) throws ServiceException {
       
        EmployeesViewSDO empSDO = serviceBean.getEmployeesView1(employeeId);
       
        EmpResult result = new EmpResult();
        result.setEmployee(empSDO);
       
        return result;
    }
   
    @GET
    @Path("depts")
    @Produces(value = { "application/json", "application/xml" })
    public DeptResult findAllDepartments() throws ServiceException {
        DeptResult result = new DeptResult();
        result.setDepartmentList(serviceBean.findDepartmentsView1(null, null));
       
        return result;
       
    }
}

Important note: For what ever reason you need to annotate the REST-Resource with @javax.inject.Singleton. Otherwise the EJB-Injection won't work.

Just reuse the SDO-Entity-classes (eg. EmployeesViewSDO), but wrap them inside a custom „Result"-class which should be annotated with @XmlRootElement (JAX-B Standard). 

@XmlRootElement

public class DeptResult {
    public DeptResult() {
        super();
    }
   
    @XmlElement(name="departments")
    private List<DepartmentsViewSDO> departmentList;

    public void setDepartmentList(List<DepartmentsViewSDO> departmentList) {
        this.departmentList = departmentList;
    }

    public List<DepartmentsViewSDO> getDepartmentList() {
        return departmentList;
    }
}
See attached sample application for the whole source code.

4. Run an see the RESTful service in action

As a result we will get the proper JSON structure


if changing the accept- Header to: application/xml we will get XML-Result. 

This is pretty cool. Because we can reuse the generated ADF BC SDO SOAP Service Layer as EJB for the REST Fassade.

Download sample application, based on Version ADF 12.1.2: enpit.sample.adf12.restadfbc-jdev1212.zip

More Information