Showing posts with label Web Services. Show all posts
Showing posts with label Web Services. Show all posts

Tuesday, November 29, 2016

Building a Successful API Strategy

As we embark into a new era of integration and connectivity, it is key to effectively communicate an API strategy. An API strategy needs to be clearconcise and executable.

Clear:
An API strategy should simply answer these questions:
  • Why are we building API's?
  • How are we building API's?
  • What are we building API's to expose?

Concise:
These answers should be concise and to the point. The answers should not be overly detailed. The detailed answers to these questions may differ slightly from different viewpoints like organizational boundaries or specific functions within an organization.

Executable:
An API strategy should align with our industry and the principles of our company. The ability to execute is the most important aspect of our API strategy.

Friday, December 17, 2010

A Mock Service with Groovy and Jetty

I recently needed to do some testing on a project that integrated with a Web service supported by another team of developers. After I completed my development work, I wanted to do some quick integration testing but I was forced to wait on the completion of the Web services. I was pretty confident that my code changes would work, but I really needed that "live" interactivity to know for sure.

In order to not be caught in this predicament again, I decided to create a simple mock service using Groovy, Jetty and some static XML files. Here is the result using an example domain model and sample data:

I put together a Groovy script to create an instance of a Jetty server. This is very similar to the example that can be found on the Groovy Web site (wink, wink).

import org.mortbay.jetty.Server
import org.mortbay.jetty.servlet.*
import groovy.servlet.*

@Grab(group = 'org.mortbay.jetty', module = 'jetty-embedded', version = '6.1.0')
def runServer = {
    def server = new Server(8181)
    def context = new Context(server, "/", Context.SESSIONS);
    
    context.resourceBase = "."
    context.addServlet(new ServletHolder(new TemplateServlet()), "*.html")
    context.addServlet(new ServletHolder(new DefaultServlet()), "*.xml")

    server.start()
}

runServer()

First, we import what we need from Jetty and here I am using @Grab to resolve our Jetty dependency.

Next, runServer is defined to do all of our work. Within runServer, we define a new Jetty Server and use it to create a new Jetty Context. I then set the context's resourceBase to "." which is the directory where the above Groovy file, mockService.groovy, is located.

Now, we need to handle requests to our server. Instead of using a standard Web descriptor, web.xml, file we can write a few line of code to add a new Groovy TemplateServlet mapped to handle the *.html request pattern and a new Jetty DefaultServlet mapped to handle the *.xml request pattern.

The Jetty DefaultServlet will handle resolving our static, test XML files.

The TemplateServlet will handle resolving and running our HTML files and it will allow us to be able to create dynamic Groovy templates like the following:

<html>
    <body>
        

File List

<% def f = new File(".") if(f.isDirectory()) { f.listFiles([accept:{file->file ==~ /.*?\.xml/}] as FileFilter).toList()*.name.each { %> ${it} <% } } %> </body> </html>


What is great about the TemplateServlet is that the above, fileList.html, contains Groovy that will be executed when the file is requested. This executed code will find all .xml files located in the current directory and display HTML links to each test XML file. For example, I have these two static, test files:

12345.xml

<?xml version="1.0" encoding="UTF-8"?>
<account>
    <id>12345</id>
    <name>Acount 12345</name>
    <address>
        <street1>123 Test St</street1>
        <city>City</city>
        <state>State</state>
        <postalcode>33333</postalcode>
    </address>
</account>

54321.xml

<?xml version="1.0" encoding="UTF-8"?>
<account>
    <id>54321</id>
    <name>Acount 54321</name>
    <address>
        <street1>123 Test St</street1>
        <city>City</city>
        <state>State</state>
    <postalcode>33333</postalcode>
    </address>
</account>


The fileList.html request will render something like:

File List


12345.xml
54321.xml

All we need to do to get started is open a command prompt, navigate to my development directory where the mockService.groovy file is located and run:

> groovy mockService.groovy

Now, my application can be configured to point to this local service. In this example, when I want to do a GET request for 'Account 12345', the application can make a call to http://localhost:8181/12345.xml. We can follow that pattern and request 'Account 54321' by calling http://localhost:8181/54321.xml or any other xxxxx.xml file I place in my development directory. I am now able to run simple integration tests with my application while the other team works to complete the final service.

To really understand the simplicity that is involved, here is a quick view of my development directory:

/mockService
- 12345.xml
- 54321.xml
- fileList.html
- mockService.groovy

Nothing too magical going on here but for me it is just another way to bring Groovy into the work environment to get things done.

Tuesday, October 21, 2008

Apache CXF: Open Source Service Framework - The Client

Earlier this year I posted Apache CXF: Open Source Service Framework to demonstrate how easy it is to create a simple echo Web Service with Apache CXF. Now I would like to post an example client for that service using Apache CXF.

First, we need our dependencies: (download them here)

...
commons-logging-1.1.1.jar
cxf-2.1.2.jar
FastInfoset-1.2.2.jar
geronimo-activation_1.1_spec-1.0.2.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-javamail_1.4_spec-1.3.jar
geronimo-jaxws_2.1_spec-1.0.jar
geronimo-servlet_2.5_spec-1.2.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.2.jar
jaxb-api-2.1.jar
jaxb-impl-2.1.7.jar
jaxen-1.1.jar
jdom-1.0.jar
jetty-6.1.9.jar
jetty-util-6.1.9.jar
neethi-2.0.4.jar
saaj-api-1.3.jar
saaj-impl-1.3.jar
spring-beans-2.0.8.jar
spring-context-2.0.8.jar
spring-core-2.0.8.jar
spring-web-2.0.8.jar
stax-utils-20060502.jar
wsdl4j-1.6.2.jar
wstx-asl-3.2.4.jar
xml-resolver-1.2.jar
XmlSchema-1.4.2.jar
...

Then we need the Echo Service interface (this should be provided for us from our service providers) :

...
package com.thejavajar.service;

import javax.jws.WebService;

@WebService
public interface EchoServiceIfc {

    public String echo(String text);
    }
    ...

The last piece of the pie is our client that makes the call out to http://localhost:9000/echo, where our service lives, in order to invoke an operation on the service.

...
package com.thejavajar.client;

import org.apache.cxf.frontend.ClientProxyFactoryBean;
import com.thejavajar.service.EchoServiceIfc;

public class EchoClient {

    public static void main(String[] args) {

        String request = new String("test 1");

        ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
        factory.setServiceClass(EchoServiceIfc.class);
        factory.setAddress("http://localhost:9000/echo");
        EchoServiceIfc client = (EchoServiceIfc) factory.create();

        System.out.println("Sending: " + request);
        String response = client.echo(request);
        System.out.println("Returned: " + response);

        System.exit(0);
    }
}
...

All we need to do is run our main method in our EchoClient class and we will get something like:

...
Sending: test 1
Returned: test 1
...


That's all folks. Obviously, this example, along with our previously posted service, is not solving complex problems that we might face in our current Java development endeavors but it provides us with peak into Apache CXF and opens up more people to a technology that I enjoy working with.

Eclipse Project: apache-cxf-echo-client.zip

Tuesday, September 02, 2008

Apache CXF: Open Source Service Framework

Web Service development has come a long way. I had some experience with XFire a few years ago and thought Web Service development could not get any easier. Then XFire became the Apache CXF project. I wanted to take a peak at Apache CXF so the other night I put together a simple echo Web Service. Alright, if you would like to follow along, you can create a Web Service in about 10 minutes:

First, we need our dependencies: (download them here)

...
commons-logging-1.1.1.jar
cxf-2.1.2.jar
FastInfoset-1.2.2.jar
geronimo-activation_1.1_spec-1.0.2.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-javamail_1.4_spec-1.3.jar
geronimo-jaxws_2.1_spec-1.0.jar
geronimo-servlet_2.5_spec-1.2.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.2.jar
jaxb-api-2.1.jar
jaxb-impl-2.1.7.jar
jaxen-1.1.jar
jdom-1.0.jar
jetty-6.1.9.jar
jetty-util-6.1.9.jar
neethi-2.0.4.jar
saaj-api-1.3.jar
saaj-impl-1.3.jar
spring-beans-2.0.8.jar
spring-context-2.0.8.jar
spring-core-2.0.8.jar
spring-web-2.0.8.jar
stax-utils-20060502.jar
wsdl4j-1.6.2.jar
wstx-asl-3.2.4.jar
xml-resolver-1.2.jar
XmlSchema-1.4.2.jar
...

Second, we need our service interface: (note the @WebService annotation)

...
package com.thejavajar.service;

import javax.jws.WebService;

@WebService
public interface EchoServiceIfc {
    public String echo(String text);
}
...

Next, we need an implementation of our service interface: (note the @WebService annotation)

...
package com.thejavajar.service;

import javax.jws.WebService;

@WebService
public class EchoServiceImpl implements EchoServiceIfc {
    public String echo(String text) {
        return text;
    }
}
...

Finally, we can create a simple Java class that will start a server and expose our service:

...
package com.thejavajar.server;

import org.apache.cxf.frontend.ServerFactoryBean;
import com.thejavajar.service.EchoServiceIfc;
import com.thejavajar.service.EchoServiceImpl;

public class Server {
    public static void main(String[] args) {
        EchoServiceImpl echoServiceImpl = new EchoServiceImpl();

        // Create our Server
        ServerFactoryBean svrFactory = new ServerFactoryBean();
        svrFactory.setServiceClass(EchoServiceIfc.class);
        svrFactory.setAddress("http://localhost:9000/echo");
        svrFactory.setServiceBean(echoServiceImpl);
        svrFactory.create();
    }
}
...

Above, we set a few properties of the ServerFactoryBean that we have instantiated. We basically set up our service interface, our address (URL) to our service endpoint and the implementation class. We can run this as a normal Java application and browse over to http://localhost:9000/echo?wsdl and see our WSDL generated for our echo service.

There is nothing too complicated about the echo service. It is basically a Java interface, an implementation class and a few annotations. This is a great start for any developer who wants to start developing Web Services without getting overwhelmed with the full capabilities and features of Apache CXF or the spec. For more information, head on over to http://cxf.apache.org.

Eclipse Project: apache-cxf-echo-service.zip