JavaXT
|
|
Express Web ServicesOne of the key features of javaxt-express is the ability to create REST services via the WebService class. Instead of defining routes in config files or annotations, the WebService class will automatically route HTTP requests to a method in your Java code using reflection. Suppose we want to implement a REST endpoint that simply returns a JSON document. All we need to do is:
ExampleIn the following example, we will create a "AdminService" WebService class with a single web method called getUsers() that simply returns a list of names as a JSON document. public class AdminService extends WebService { public ServiceResponse getUsers(ServiceRequest request) throws Exception { JSONArray users = new JSONArray(); users.add("peter"); users.add("paul"); users.add("mary"); users.add("jane"); return new ServiceResponse(users); } } To host this service, we will create a simple web server with an HttpServlet. The processRequest() method of the HttpServlet is used to read HTTP requests and send a response to the client. Inside the processRequest() method we will route requests to the AdminService. //Start a web server with an HttpServlet int port = 9080; int numThreads = 50; new javaxt.http.Server(port, numThreads, new HttpServlet() { //Instantiate the AdminService private AdminService adminService = new AdminService(); //Create an implementation of the processRequest method for the HttpServlet public void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { //Wrap the HTTP request in a ServiceRequest ServiceRequest serviceRequest = new ServiceRequest(request); //Get response from the AdminService ServiceResponse serviceResponse = adminService.getServiceResponse(serviceRequest); //Send response to the client serviceResponse.send(response, serviceRequest); } }).start();In this simple example, the AdminService service will be called whenever a new HTTP request is recieved. The getUsers() method in the AdminService class will be invoked automatically whenever the web server processes a GET /usersrequest (e.g. http://localhost:9080/users). All other requests will return a 501 response. Routing LogicThe logic for picking a method to call is quite simple. If the client performs a HTTP "GET" request, the server will try to find a suitable "get" method using the first path after the "servlet" path. If the client performs a HTTP "DELETE" request, the server will try to find a suitable "delete" method. And if the client performs a HTTP "POST" or "PUT" request, the server will try to find a suitable "save" method. In our simple example, the following requests map to the web methods in the AdminService like this:
To support these routes, we will have to create new REST service endpoints. Example: public ServiceResponse getUser(ServiceRequest request) throws Exception { //TODO: Return response for HTTP "GET" request to http://localhost:9080/user?id=123 } public ServiceResponse deleteUser(ServiceRequest request) throws Exception { //TODO: Return response for HTTP "DELETE" request to http://localhost:9080/user?id=123 } public ServiceResponse saveUser(ServiceRequest request) throws Exception { //TODO: Return response for HTTP "POST" or "PUT" request to http://localhost:9080/user } If a suitable method is not defined, the server will return a 501 response. Models, Persistence, and CRUDIn the examples above we showed how javaxt-express routes HTTP requests to concrete methods in the AdminService. We can simplify this further by using javaxt.sql.Models generated by the javaxt-orm library. With javaxt-orm, you can create a javaxt.sql.Model using a model spec (json or js file) and it will generate classes that you can incorporate into your project (e.g. User.java). Assuming you add the models to your project and initialize them with a ConnectionPool, you can register the models with the WebService like this: public class AdminService extends WebService { public AdminService(){ addClass(User.class); } } If you register a model like this, you don't actually need to implement your own getUser(), getUsers(), saveUser(), and deleteUser() methods. These CRUD methods will be provided automatically by the WebService class. The javaxt.express.Server command line interface takes this one step further and doesn't require concrete javaxt.sql.Model classes. Instead, all you have to do is pass in a model spec file (json or js) and it will create, initialize, and register the models in a completely abstract way. |