At the client side I have angular code calling PUT:
$http.put('organization', {name: $scope.name}).success( function(data){ alert('Success'); });the GET, POST and DELETE will be more or less the same. $http.get(), $http.post(), $http.delete().
One thing I found interesting about slim3 is the URL rewrite with AppRouter.java. Here is what I do (with evil smile):
addRouting( "/secured/{entity}", "/secured/rest?entity={entity}"); addRouting( "/secured/{entity}/{resourceId}", "/secured/rest?entity={entity}&resourceId={resourceId}");
I route both URL to the same Controller. So here is my Controller. My root package is "smis". (I know, I know...)
package smis.controller.secured; import java.io.BufferedReader; import java.lang.reflect.Method; import java.util.List; import org.apache.log4j.Logger; import org.slim3.controller.Controller; import org.slim3.controller.Navigation; import org.slim3.datastore.Datastore; import org.slim3.datastore.ModelMeta; import com.google.appengine.api.datastore.Key; public class RestController extends Controller { private Logger logger = Logger.getLogger(getClass()); @Override public Navigation run() throws Exception { String entityName = asString("entity"); String resourceId = asString("resourceId"); // hack class name. :p entityName = entityName.substring(0, 1).toUpperCase() + entityName.substring(1); Class entityClass = Class.forName("smis.model." + entityName); Class modelMetaClass = Class.forName("smis.meta." + entityName + "Meta"); Method method = modelMetaClass.getMethod("get"); Object modelMetaInstance = method.invoke(null); logger.debug(entityClass); logger.debug(modelMetaClass); logger.debug(modelMetaInstance); logger.debug("Method = " + request.getMethod()); if (isGet()) { if (resourceId == null) { return handleList((ModelMeta) modelMetaInstance); } else { return handleDetail(entityClass, (ModelMeta) modelMetaInstance); } } else if (isPost()) { return handleCreate((ModelMeta) modelMetaInstance); } else if (isPut()) { return handleCreate((ModelMeta) modelMetaInstance); } else if (isDelete()) { return handleDelete(entityClass); } return null; } private Navigation handleDelete(Class entityClass) throws Exception { Key key = asKey("resourceId"); Datastore.delete(key); Object t = Datastore.get(entityClass, key); logger.debug(t == null); response.setContentType("text/plain"); response.setCharacterEncoding("UTF-8"); response.getWriter().print(t == null); response.flushBuffer(); return null; } private Navigation handleCreate(ModelMeta modelMeta) throws Exception { StringBuffer jb = new StringBuffer(); String line = null; try { BufferedReader reader = request.getReader(); while ((line = reader.readLine()) != null) jb.append(line); } catch (Exception e) { /* report an error */ e.printStackTrace(); } String json = jb.toString(); logger.debug(json); Object t = modelMeta.jsonToModel(json); boolean isComplete = Datastore.put(t).isComplete(); logger.debug(isComplete); response.setContentType("text/plain"); response.setCharacterEncoding("UTF-8"); response.getWriter().print(isComplete); response.flushBuffer(); return null; } private Navigation handleDetail(Class entityClass, ModelMeta modelMeta) throws Exception { Key key = asKey("resourceId"); logger.debug(key); Object t = Datastore.get(entityClass, key); String json = modelMeta.modelToJson(t); logger.debug(json); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); response.getWriter().print(json); response.flushBuffer(); return null; } private Navigation handleList(ModelMeta modelMeta) throws Exception { List list = Datastore.query(modelMeta).asList(); String json = modelMeta.modelsToJson(list); logger.debug(json); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); response.getWriter().print(json); response.flushBuffer(); return null; } }Because my lazy nature, I use reflection to create the Class for my entity and also the instance of the Meta class. Thanks to how slim3 name the model and meta class. There is a high security risk here! Not recommended for production, OK?
Then based on the isXXX() functions I call the handleXXXXX() accordingly. The implementation explains itself.
Some more interesting would be the asKey("my_key"), it does the same thing like:
request.getParameter("my_key") + parse it into a Key.
Very handy.
Last thing to point out is how to digest the request data:
StringBuffer jb = new StringBuffer(); String line = null; try { BufferedReader reader = request.getReader(); while ((line = reader.readLine()) != null) jb.append(line); } catch (Exception e) { /* report an error */ e.printStackTrace(); }
The experiment was fun. I enjoy writing and playing with it. Hope it is the same for you too.
No comments:
Post a Comment