Fork me on GitHub

n. Slang a rough lawless young Kuali developer.
[perhaps variant of Houlihan, Irish surname]
kualiganism n

Blog of an rSmart Java Developer. Full of code examples, solutions, best practices, et al.

Tuesday, November 18, 2014

ReST Services in Rice (Jersey and JAX-WS)

The Options

There are a couple ways to implement ReST services within Rice. The ones I want to discuss is to use the KSB or to use Jersey. There are probably other ways available to do this, but I like these options. I'll explain why along with how.

KSB

I can't say that any solution is simpler than the other. They all have their ups and downs. For example, IMHO, the KSB option is by far the most configuration intensive and complicated path. However, once you understand how it works and how everything is wired together, it is less daunting of an undertaking. The difficulty curve for using the KSB is exactly that. It's a curve because the difficulty increases with the number of services you decide you want to implement. More services means more configuration. More configuration means more maintenance. We all love maintenance right? No, not really. I'm not doing a very good job of selling it, am I? Why bother with the KSB approach then? Well, if you're using the KSB at all, it's because you want to create a platform of service peers that communicate with each other and share services. Otherwise, why bother with a service bus at all, right? I will break it down.

Pro's

  • Share and interact services with applications connected to the Kuali Platform.
  • Access to KEW.
  • Simple services that can be accessed through HTTP.
  • HTTP for authentication.

Con's

  • Excessive configuration required per service.

Jersey


Jersey is another approach besides the KSB. It is a pretty solid and comprehensive ReST implementation available for Java that integrates with Spring. It is pretty easy to setup and use. Adding additional services is really simple. The downside is that the KSB requires and exporter to export spring services. Jersey doesn't do this for us; therefore, you lose interaction with
the KSB.

Pro's

  • Create a ReST interface to services available in your Rice application.
  • Access to KEW.
  • HTTP for authentication.
  • Super simple configuration and setup.

Con's

  • No sharing of services over the KSB.

Example

I created a Sample Project to illustrate both sides here. I'm also going to use this project in another blog post. Therefore, it's a pretty comprehensive project. I want to explain this project and its modules before going forward and explaining how KSB and Jersey configuration is handled. Don't worry, it's not complex. This won't take long.

client

Of course, in order to show how to communicate with KSB or Jersey and to prove that all this works, it needs a client, right? That's what this is. This is a module that houses the client I am going to use to test out whether things work correctly or not.

api

This is the the only dependency the client will need. The idea is that when you build web services, you are remotely executing functionality. This means that the implementation is hidden. All that is known is an interface. This is what api is. It's just an interface to tell the client what to expect. There is absolutely no implementation in it whatsoever. In the end, everything depends on the api module in some way. The only 2 classes in this module are the OrganizationService.java interface and the Organization.java interface.




You may have noticed above in the Organization.java, the use of @XmlElement, @XmlRootElement, and others. These are JAX-WS annotations that, despite their names, are used in conversion to/from JSON.

model

The model is just what it sounds like. It's the only POJO in the sample pretty much. It's a concrete class, so I separate it from the api and from the services. The


A couple things you might notice about this Organization.java is that it's a concrete class, it inherits from the interface defined in the api module, and it does not contain the JAX-WS annotations. This is on purpose to prevent the model from being tainted by JAX-WS.

impl

impl is where I stored all the service implementations. This also includes the ReST services.



This is the implementation of the OrganizationService.java. It's very simple. Notice that all that is really done is an instance of the model is created and returned using the api interface.



This is a service that wraps the original OrganizationServiceImpl. This is necessary to separate the OrganizationServiceImpl from Jersey and keep it from knowing details about JSON, Jersey, or Jackson. JsonOrganizationService is responsible for creating a JSON response and answering/handling the JSON request. Notice also that the JsonOrganizationService has a @Component annotation. This is used for component scanning which I explain the configuration for later.

web/ksb

This module handles the KSB specific configuration of the example. It actually creates a WAR artifact which means this is the actual application as implemented with KSB.

For this, there isn't any POM modification or setup needed. It's baked into your Kuali Application. What we do need is this:



In my BootStrapSpringBeans.xml file, I needed to add several beans. If I add another service, many similar beans will need to be added again. The first thing I needed to do was to import the serviceBus from the KSB spring context. Next, we can see that I had to add two beans for the service and its wrapper. I didn't bother with the autowiring, but I could have made use of that here.

The important part is RestServiceDefinition and the ServiceBusExporter. There are many different definitions available. Since I want to make use of ReST, I used the RestServiceDefinition. Having the definition isn't good enough though. Once the definition is configured and points to the originating jsonOrganizationService, it now needs to be used to export the actual jsonOrganizationService to the serviceBus. That is why we needed to import the serviceBus bean. Otherwise, exporting the service would be impossible. Now the configuration is complete. We can start up the application and test out the url.

web/jersey

Just like web/ksb, this creates a WAR artifact and is the same application only configured to use Jersey.

1. Setup the POM




Here we had to add some dependencies to the POM for Jersey.



In the web.xml, I added:
  • ContextLoaderListener
  • jersey-servlet. I had to specify com.github.kualigan.ducktyping.rest as a package to accept for ReST services.



This is actually located in WEB-INF. You can see that it defines as a bean our organizationService this will get autowired into our JsonOrganizationService. Since the JsonOrganizationService is a @Component in the com.github.kualigan.ducktyping.rest package, it will get picked up by the component scan.

Running the example

Starting up the application is pretty easy.

For Jersey

% mvn -pl web/jersey jetty:run

After that, you just browse to the url: http://localhost:8080/ducktyping-example/rest/Organization/get/1

For KSB

% mvn -pl web/ksb jetty:run

After that, you just browse to the url: http://localhost:8080/ducktyping-example/remoting/jsonOrganizationService/Organizations/get/1

No comments:

Post a Comment