/* * Copyright IBM Corp. 2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.bluemix.todo.rest; import java.util.Collection; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import net.bluemix.todo.model.ToDo; import net.bluemix.todo.store.ToDoStore; import net.bluemix.todo.store.ToDoStoreException; import net.bluemix.todo.store.ToDoStoreFactory; /** * REST API for performing basic CRUD operations on TODOs. */ @Path("todos") public class ToDoAPI { private ToDoStore store; /** * Default constructor. This is used by the Jersey framework. * @throws ToDoStoreException Thrown if a store cannot be retrieved. */ public ToDoAPI() throws ToDoStoreException { this.store = ToDoStoreFactory.getInstance(); } /** * Constructor. Used mainly for testing purposes. * @param store The ToDo store to use. */ public ToDoAPI(ToDoStore store) { this.store = store; } /** * Gets a given ToDo. * REST API example: * <code> * GET http://localhost:8080/api/todos/123 * </code> * * Response: * <code> * { * "completed":false, * "id":"1393339172666", * "title":"get the kids" * } * </code> * @param id The ID of the ToDo. * @return The ToDo for the given ID. */ @GET @Path("/{id}") @Produces("application/json") public ToDo getToDo(@PathParam("id") String id) { if(id == null) { throw new WebApplicationException("Must supply an ID, for example /api/todos/123.", Response.Status.BAD_REQUEST); } try { ToDo td = store.get(id); if(td == null) { throw new WebApplicationException("ToDo with the ID " + id + " does not exist.", Response.Status.BAD_REQUEST); } return td; } catch (ToDoStoreException e) { throw new WebApplicationException("Error getting ToDo.", Response.Status.INTERNAL_SERVER_ERROR); } } /** * Gets all ToDos. * REST API example: * <code> * GET http://localhost:8080/api/todos * </code> * * Response: * <code> * [ * { * "completed":false, * "id":"1393339172666", * "title":"get the kids" * }, * { * "completed":false, * "id":"123", * "title":"pick up milk" * } * ] * </code> * @return A collection of all the ToDos */ @GET @Produces("application/json") public Collection<ToDo> getToDos() { try { return store.getAll(); } catch (ToDoStoreException e) { throw new WebApplicationException("Error getting all ToDos.", Response.Status.INTERNAL_SERVER_ERROR); } } /** * Creates a new ToDo. * * REST API example: * <code> * POST http://localhost:8080/api/todos * <code> * POST Body: * <code> * { * "title":"pick up milk" * } * </code> * Response: * <code> * { * "completed":false, * "id":"123", * "title":"pick up milk" * } * </code> * @param td The new ToDo to create. * @return The ToDo after it has been stored. This will include a unique ID for the ToDO. */ @POST @Consumes("application/json") @Produces("application/json") public ToDo newToDo(ToDo td) { if(td == null) { throw new WebApplicationException("Must supply a ToDo in the POST body.", Response.Status.BAD_REQUEST); } try { return store.persist(td); } catch (ToDoStoreException e) { throw new WebApplicationException("Error saving ToDo.", Response.Status.INTERNAL_SERVER_ERROR); } } /** * Updates a ToDo. * * REST API example: * <code> * PUT http://localhost:8080/api/todos/456 * </code> * PUT Body: * <code> * { * "completed":false, * "id":"123", * "title":"pick up milk" * } * </code> * Response: * <code> * { * "completed":false, * "id":"456", * "title":"pick up milk" * } * </code> * @param id The ID of the ToDo to update. * @param td The data for the ToDo to be updated with. * @return The updated ToDo. */ @PUT @Path("/{id}") @Produces("application/json") @Consumes("application/json") public ToDo updateToDo(@PathParam("id") String id, ToDo td) { if(id == null) { throw new WebApplicationException("Must supply an ID, for example /api/todos/123.", Response.Status.BAD_REQUEST); } if(td == null) { throw new WebApplicationException("Must supply a ToDo in the PUT body.", Response.Status.BAD_REQUEST); } try { ToDo updatedTd = store.update(id, td); if(updatedTd == null) { throw new WebApplicationException("The ToDo with the ID " + id + " does not exist.", Response.Status.BAD_REQUEST); } return updatedTd; } catch (ToDoStoreException e) { throw new WebApplicationException("Error updating ToDo.", Response.Status.INTERNAL_SERVER_ERROR); } } /** * Deletes a ToDo. * * REST API example: * <code> * DELETE http://localhost:8080/api/todos/456 * </code> * @param id The ID of the ToDo to delete. */ @DELETE @Path("/{id}") public void deleteToDo(@PathParam("id") String id) { if(id == null) { throw new WebApplicationException("Must supply an ID, for example /api/todos/123,", Response.Status.BAD_REQUEST); } try { store.delete(id); } catch (ToDoStoreException e) { throw new WebApplicationException("Error deleting ToDo.", Response.Status.INTERNAL_SERVER_ERROR); } } }