Platinum Partner
java,enterprise-integration,json,rest,integration,tips and tricks

REST-JSON Service Definition Simplified

In continuation from my previous post on REST-JSON Service Versioning here are my thoughts around service definition for REST-JSON.

Problem Statement:

As a service provider, one is obliged to document the service contract (request/response) of the service exposed to consumers.

If you take the SOAP/web-service world for an analogy, WSDL acts as a contract for the services exposed. This article is an attempt to see how a JSON schema can be exposed via generic services/wrappers.

Note: I have chosen Spring MVC + Jackson Library as software stack for the solution approach.

Ex:

1.  Let’s taken an example of Service below that returns an employee object, given an employee Id.

@Controller
public class TestController {
	
	@RequestMapping(value="/employee", method=RequestMethod.GET)
	public ResponseEntity<Employee> fetchEmployee(){
		Employee employee = new Employee();
		return new ResponseEntity<Employee>(employee, HttpStatus.OK);
	}
	
   }

2.  The Employee response object could look something like this,

public class Employee {
private int employeeId;
private String name;
private long primaryNumber;
	
	public int getEmployeeId() {
		return employeeId;
	}

	public String getName() {
		return name;
	}

	public long getPrimaryNumber() {
		return primaryNumber;
	}
}

Solution:

Based on the problem statement, the solution proposed below would seamlessly discover the REST-JSON services exposed in your application.

1.  To do so, I have introduced an implementation/overridden class on top of Json Serialize/De-Serialize - DiscoverableService.java

/**
 * Extending DiscoverableService means the exposed service is enabled for auto
 * discovery.
 */
public abstract class DiscoverableService {

	/**
	 * @return
	 */
	public List<ServiceInfo> getAllExposedServiceInfo() {
		
	 . . . . 
	}
}

2.  Now any new service developed should extend DiscoverableService.java, to mark itself as exposed service for service discovery.

@Controller
public class TestController extends DiscoverableService {
	
	@RequestMapping(value="/employee", method=RequestMethod.GET)
	public ResponseEntity<Employee> fetchEmployee(){
	    Employee employee = new Employee();
 		    return new ResponseEntity<Employee>(employee,HttpStatus.O)
	}
}

3.  I have a controller/service exposed for the service discovery information, which is ServiceController.java.

Spring Auto wires all the controllers in the context that extend DiscoverableService to this controller class as shown below.

@Controller
public class ServiceController {

@Autowired
protected List<DiscoverableService> discoverableServices;	

@RequestMapping(value = "/service", method = RequestMethod.GET)
public synchronized ResponseEntity<List<ServiceInfo>> fetchAllServiceInfo() {
	List<ServiceInfo> serviceInfos = new ArrayList<ServiceInfo>();
	for (DiscoverableService service : discoverableServices) {
		serviceInfos.addAll(service.getAllExposedServiceInfo());
	}
	return new ResponseEntity<List<ServiceInfo>>(serviceInfos,
				HttpStatus.OK);
}

}. . . . 

4.  Now comes the simple & final step, access your service information

http://localhost:8080/web-context/service/employee will return service definition for fetchEmployee service.

[{
"serviceURI": "/employee",
"requestMethod": ["GET" ],
"methodName": "class com.sample.controller.TestController.fetchEmployee()",
"request": [ ],
"response": {
"employeeId": 0,
"name": null,
"primaryNumber": 0
}}]

5.  http://localhost:8080/web-context/service  - returns definition of all services exposed by the system.

Conclusion:

With the above approach, exposing service/contract definition to consumers will be seamless.  Just sharing the service definition to the service consumer would do the trick.

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}