How should you encode the strings in a JSON document? The topic can be a bit confusing. Let’s talk about it in this post.
Continue readingCategory Archives: Web Service
RESTful Web Service using Spring Boot and VS Code
VS Code has become quite a useful IDE to develop Spring applications. In this article we will explore what it takes to develop a web service from scratch.
Continue readingKoa in 10 Minutes
In this article we will explore web service development using Koa. We will also look at some of the really cool things about Koa.
Calling JAX-RS Service Using AJAX Client
At the time of this writing, there is no standard way to generate AJAX client proxy for a JAX-RS RESTful service. You will find yourself writing a lot of code in the client side just to invoke these services. Several JAX-RS implementations provide their own proprietary client code generation solution. In this article, I will discuss how to generate a client if you are using RESTeasy. JBoss AS 7.1 uses RESTeasy by default which is what I used to test my work.
Let’s say that we have a very simple service resource class.
@Path("/svc") public class MyBean { @Path("/value") @Produces("text/plain") @GET public String getValue() { return "Some value"; } }
First, register the code generation servlet in web.xml.
<listener> <listener-class> org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap </listener-class> </listener> <servlet> <servlet-name>RESTEasy JSAPI</servlet-name> <servlet-class>org.jboss.resteasy.jsapi.JSAPIServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>RESTEasy JSAPI</servlet-name> <url-pattern>/rest-api.js</url-pattern> </servlet-mapping>
This binds the “/rest-api.js” path to the generated JavaScript. You can use any other path if you like.
In your HTML file, import the client side script.
<script type="text/javascript" src="rest-api.js"></script>
Note, “res-api.js” is the path to the JSAPIServlet as registered in web.xml.
The script defines a JavaScript object for every JAX-RS resource class by the same name. In our case, we will get a variable called MyBean. This JavaScript object has a method for each exposed method of the JAX-RS resource class. In our case, the name of the method will be getValue().
Let’s go ahead and code the rest of the HTML file.
<head> <script type="text/javascript" src="rest-api.js"></script> <script type="text/javascript"> function doTest() { MyBean.getValue({$callback: onResult}); } function onResult(status, xhr, data) { console.log("Status is: " + status); if (status == 200) alert(data); else console.log("Do error handling"); } </script> </head> <body> <button onclick="doTest();">Test</button> </body>
Basically, MyBean.getValue() method takes a parameter object. At minimum, we need to supply the callback method which is set using the $callback property. The callback method receives three input parameters:
- The HTTP reply status. Use this to do error handling.
- The XmlHttpRequest object used to make the AJAX call.
- The actual reply data. If the response is a JSON document, then system parses it and gives you the JavaScript object. If the response is XML, then you get the Document object. Otherwise, you get the raw response data as is.
For more information, see the official doc on RESTeasy AJAX client programming.
Developing JAX-RS Services With JBoss AS 7
This morning, I tried to write a RESTful service using JBoss AS 7 and JBoss plugins for Eclipse Indigo. The process to setup a dynamic web project for JAX-RS is a little tricky.
First of all, do’t just go ahead and try to add the JAX-RS facet to the dynamic web project. Instead, right click the project and select Add JAX-RS 1.1 Support.
Then, open web.xml, and add these lines:
<servlet> <servlet-name>javax.ws.rs.core.Application</servlet-name> </servlet> <servlet-mapping> <servlet-name>javax.ws.rs.core.Application</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping>
You can use anything else in place of “/rest/*”. Any URI starting with this will be routed to the JAX-RS servlet.
Let’s say that we have a class:
@Path("/mybean") public class MyBean { @Path("/value") @Produces("text/plain") @GET public String getValue() { return "Some value"; } }
Let’s say that the context root of the web project is “MyWeb”. Now, you can access the getValue() method of the MyBean resource using the URI: /MyWeb/rest/mybean/value.
A Documentation Model for a RESTful API
In this article, I propose a documentation structure for RESTful Web Services.
RESTful Web Services lack any standard for modeling. By that I mean, the URI syntax, HTTP method, response code etc. are all left up to the API designer. Without a clear documentation, developers can be left guessing about exactly how to invoke a service. There is a reason good documentation is considered a key best practice in a RESTful API design.
I have seen pretty messy documentation, some from fairly well known companies. Don’t let that happen to you.
What Needs to be Documented?
There are some factors that are common to all entry points or operations of the service. They need to be documented in one place:
- The base URL consisting of the protocol and host name only.
- Any details about the authentication scheme.
For each entry point (or operation) supported by the API, document these items.
General:
- What does the operation do?
- What are the security requirements? Is SSL or authentication required?
For the request:
- The HTTP method.
- URI syntax. This may contain the base URL for ease of use.
- URL parameters if any.
- Request body parameters if any.
- Supported MIME types (Content-type request header).
For the response:
- Meaning of various HTTP reply codes.
- Schema of the response body in success situation.
- Schema of the response body in error situations.
The URI Syntax
URI is used to uniquely identify a resource or a specific collection of resources. It should be documented using place holder parameters. Example:
/api/v2/products/{productId}
Or,
http://www.example.com/api/v2/products/productId
Name | Type | Description |
productId | Integer | The ID of the product |
URL Parameters
URL parameters are normally used with GET requests only. They provide filtering and sorting criteria. They should be documented using place holder parameters.
/api/v2/products/categories/{categoryId}?sortBy={sortBy}&maxSize={maxSize}
Name | Type | Description |
sortBy | String | How to sort the results. Possible values: PRICE, ALPHABATIC. Optional. Default is PRICE. |
maxSize | Integer | Maximum number of products returned. Optional. Default is 100. |
Request Body Parameters
Request Body Parameters
Request body is normally used with PUT and POST requests. They are listed in a table similar to the URL parameters.
Describing the Response Body Schema
Most APIs use examples to describe the schema. This is not a bad way. For XML response, it may be useful to also attach a schema document.
Example Case Study
Get a Product
URI
http://www.example.com/api/v2/products/productId?lang=lang¤cy=currency
Name | Type | Description |
productId | Integer | The ID of the product |
HTTP Method: GET
URL Parameters
Name | Type | Description |
lang | String | The language code in which the description of the product will be returned. Possible values en, fr and es. Optional. Defaults to browser’s language setting. |
currency | String | Currency in which prices are returned. Possible values USD, CAD and EUR. Optional. Default is USD. |
MIME Types
text/xml, application/xml and application/json
HTTP Reply Codes
Code | Meaning |
200 | Success |
404 | Product not found. Check the ID. |
500 | Invalid language or currency setting. |
Response Body on Success
XML:
<product>
<id>1001</id>
<price>172.00<price>
<currency>USD</currency>
<image>http://images.example.com/small/1001.png</image>
<name>Baseball gloves</name>
<description>…</description>
</product>
JSON:
{
“id”: 1001,
“price”: 172.00,
“currency”: “USD”,
“image”: “http://images.example.com/small/1001.png”,
“description”:”…”
}