| 946 | |
| 947 | === Providing a RESTful web service === |
| 948 | |
| 949 | Until here your plugin service is accessible from within the OSGi environment only. You can make the service accessible from //outside// the OSGi environment as well by promoting it to a RESTful web service. Your plugin service is then accessible from external applications via HTTP. (External application here means both, the client-side portion of a DeepaMehta plugin, or an arbitrary 3rd-party application). |
| 950 | |
| 951 | To provide a RESTful web service you must provide a generic plugin service first (as described above in [[#Providingaservice|Providing a service]]) and then make it RESTful by using JAX-RS annotations. With JAX-RS annotations you basically control how HTTP requests will be mapped to your service methods. |
| 952 | |
| 953 | To make your plugin service RESTful you must: |
| 954 | |
| 955 | * Annotate the plugin main class with `@Path` to anchor the plugin service in URI space. |
| 956 | |
| 957 | * Annotate the plugin main class with `@Consumes` and `@Produces` to declare the supported HTTP request and response media types. You can use these annotations also at a particular service method to override the class-level defaults. |
| 958 | |
| 959 | * Annotate each service method with one of `@GET`, `@POST`, `@PUT`, or `@DELETE` to declare the HTTP method that will invoke that service method. |
| 960 | |
| 961 | * Annotate each service method with `@Path` to declare the URI template that will invoke that service method. The URI template can contain parameters, notated as `{...}`. |
| 962 | |
| 963 | * Annotate service method parameters with `@PathParam` to map URI template parameters to service method parameters. |
| 964 | |
| 965 | As an example let's see how the //Topicmaps// plugin (part of the DeepaMehta Standard Distribution) annotates its main class and service methods: |
| 966 | |
| 967 | {{{ |
| 968 | #!java |
| 969 | package de.deepamehta.plugins.topicmaps; |
| 970 | |
| 971 | import de.deepamehta.plugins.topicmaps.model.Topicmap; |
| 972 | import de.deepamehta.plugins.topicmaps.service.TopicmapsService; |
| 973 | |
| 974 | import de.deepamehta.core.Topic; |
| 975 | import de.deepamehta.core.osgi.PluginActivator; |
| 976 | import de.deepamehta.core.service.ClientState; |
| 977 | |
| 978 | import javax.ws.rs.GET; |
| 979 | import javax.ws.rs.PUT; |
| 980 | import javax.ws.rs.POST; |
| 981 | import javax.ws.rs.DELETE; |
| 982 | import javax.ws.rs.HeaderParam; |
| 983 | import javax.ws.rs.Path; |
| 984 | import javax.ws.rs.PathParam; |
| 985 | import javax.ws.rs.Produces; |
| 986 | import javax.ws.rs.Consumes; |
| 987 | |
| 988 | |
| 989 | |
| 990 | @Path("/topicmap") |
| 991 | @Consumes("application/json") |
| 992 | @Produces("application/json") |
| 993 | public class TopicmapsPlugin extends PluginActivator implements TopicmapsService { |
| 994 | |
| 995 | // *** TopicmapsService Implementation *** |
| 996 | |
| 997 | @POST |
| 998 | @Path("/{name}/{topicmap_renderer_uri}") |
| 999 | @Override |
| 1000 | public Topic createTopicmap(@PathParam("name") String name, |
| 1001 | @PathParam("topicmap_renderer_uri") String topicmapRendererUri, |
| 1002 | @HeaderParam("Cookie") ClientState clientState) { |
| 1003 | ... |
| 1004 | } |
| 1005 | |
| 1006 | @GET |
| 1007 | @Path("/{id}") |
| 1008 | @Override |
| 1009 | public Topicmap getTopicmap(@PathParam("id") long topicmapId, @HeaderParam("Cookie") ClientState clientState) { |
| 1010 | ... |
| 1011 | } |
| 1012 | |
| 1013 | @POST |
| 1014 | @Path("/{id}/topic/{topic_id}/{x}/{y}") |
| 1015 | @Override |
| 1016 | public void addTopicToTopicmap(@PathParam("id") long topicmapId, @PathParam("topic_id") long topicId, |
| 1017 | @PathParam("x") int x, @PathParam("y") int y) { |
| 1018 | ... |
| 1019 | } |
| 1020 | |
| 1021 | ... |
| 1022 | }}} |
| 1023 | |
| 1024 | |
| 1025 | |
| 1026 | JAX-RS: Java API for RESTful Web Services |
| 1027 | http://jsr311.java.net/nonav/releases/1.1/spec/spec.html |