QBit Restful MicroservicesBefore we delve into QBit restful services, let's cover what we get from gradle's application plugin. In order to be a microservice, a service needs to run in a standalone process or a related group of standalone processes. ... (Read full article at Creating Java RESTful Microservices) ... Creating a simple RestFul MicroserviceLet's create a simple HTTP service that responsds with pong when we send it a ping as follows. Service that responds to this curl command$ curl http://localhost:9090/services/pongservice/ping
"pong" First let's import the qbit lib. We are using the SNAPSHOT but hopefully by the time you read this the release will be available. Add the following to your gradle build. Adding QBit to your gradle buildapply plugin: 'java' apply plugin:'application' sourceCompatibility = 1.8 version = '1.0' mainClassName = "io.advantageous.examples.Main" repositories { mavenLocal() mavenCentral() } dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' compile group: 'io.advantageous.qbit', name: 'qbit-vertx', version: '0.7.3-SNAPSHOT' } Define a service as follows: QBit servicepackage io.advantageous.examples; import io.advantageous.qbit.annotation.RequestMapping; @RequestMapping public class PongService { @RequestMapping public String ping() { return "pong"; } } The @RequestMapping defines the service as one that responsds to an HTTP call. If you do not specify the path, then the lower case name of the class and the lower case name of the method becomes the path. Thus PongService.ping() becomes /pongservice/ping. To bind this service to a port we use a service server. A service server is a server that hosts services like our pong service. Change the Main class to use the ServiceServer as follows: Using main class to bind in service to a portpackage io.advantageous.examples; import io.advantageous.qbit.server.ServiceServer; import io.advantageous.qbit.server.ServiceServerBuilder; public class Main { public static void main(String... args) { final ServiceServer serviceServer = ServiceServerBuilder .serviceServerBuilder() .setPort(9090).build(); serviceServer.initServices(new PongService()); serviceServer.startServer(); } } Notice we pass an instance of the PongService to the initServices of the service server. If we want to change the root address from "services" to something else we could do this: Changing the root URI of the service serverfinal ServiceServer serviceServer = ServiceServerBuilder .serviceServerBuilder() .setUri("/main") .setPort(9090).build(); serviceServer.initServices(new PongService()); serviceServer.startServer(); Now we can call this using curl as follows: Use the curl command to invoke service via /main/pongservice/ping$ curl http://localhost:9090/main/pongservice/ping
"pong" QBit uses builders to make it easy to integrate QBit with frameworks like Spring or Guice or to just use standalone. Adding a service that takes request paramsTaking request parameterspackage io.advantageous.examples; import io.advantageous.qbit.annotation.RequestMapping; import io.advantageous.qbit.annotation.RequestParam; @RequestMapping("/my/service") public class SimpleService { @RequestMapping("/add") public int add(@RequestParam("a") int a, @RequestParam("b") int b) { return a + b; } } Notice the above uses @RequestParam this allows you to pull the requests params as arguments to the method. If we pass a URL like: http://localhost:9090/main/my/service/add?a=1&b=2. QBit will use 1 for argument a and 2 for argument b. Adding the new service to Mainpackage io.advantageous.examples; import io.advantageous.qbit.server.ServiceServer; import io.advantageous.qbit.server.ServiceServerBuilder; public class Main { public static void main(String... args) { final ServiceServer serviceServer = ServiceServerBuilder .serviceServerBuilder() .setUri("/main") .setPort(9090).build(); serviceServer.initServices( new PongService(), new SimpleService()); serviceServer.startServer(); } } When we load this URL: http://localhost:9090/main/my/service/add?a=1&b=2 We get this response. HTTP/1.1 200 OK Content-Type: application/json Content-Length: 1 3 Working with URI paramsMany think that URLs without request parameters are more search engine friendly or you can list things under a context which make it more RESTful. This is open to debate. I don't care about debate, but here is an example of using URI params. Working with URI params examplepackage io.advantageous.examples; import io.advantageous.qbit.annotation.PathVariable; import io.advantageous.qbit.annotation.RequestMapping; import io.advantageous.qbit.annotation.RequestParam; @RequestMapping("/my/service") public class SimpleService { ... ... @RequestMapping("/add2/{a}/{b}") public int add2( @PathVariable("a") int a, @PathVariable("b") int b) { return a + b; } } Now we can pass arguments which are part of the URL path. We do this by using the @PathVariable annotation. Thus the following URL:
The 1 is correlates to the "a" argument to the method and the 4 correlates to the "b" arguments. We would get the following response when we load this URL. Working with URI params outputHTTP/1.1 200 OK Content-Type: application/json Content-Length: 1 5 You can mix and match URI params and request params. Working with URI params and request params examplepackage io.advantageous.examples; import io.advantageous.qbit.annotation.PathVariable; import io.advantageous.qbit.annotation.RequestMapping; import io.advantageous.qbit.annotation.RequestParam; @RequestMapping("/my/service") public class SimpleService { ... ... @RequestMapping("/add3/{a}/") public int add3( @PathVariable("a") int a, @RequestParam("b") int b) { return a + b; } } This allows us to mix URI params and request params as follows:
Now we get this response: Working with URI params and request params exampleHTTP/1.1 200 OK Content-Type: application/json Content-Length: 1 9 Fuller RESTful exampleRead full article at Creating Java RESTful Microservices. |