nitrestful: support custom resource name and HTTP methods/verbs
authorAlexis Laferrière <alexis.laf@xymus.net>
Mon, 30 Nov 2015 17:37:27 +0000 (12:37 -0500)
committerAlexis Laferrière <alexis.laf@xymus.net>
Tue, 11 Oct 2016 20:09:39 +0000 (16:09 -0400)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

src/nitrestful.nit

index 1f955ce..a4005d0 100644 (file)
@@ -37,6 +37,24 @@ private class RestfulPhase
                        return
                end
 
+               var http_resources = new Array[String]
+               var http_methods = new Array[String]
+               for arg in nat.n_args do
+                       var str = arg.as_string
+                       var id = arg.collect_text
+                       if str != null then
+                               # String -> rename resource
+                               http_resources.add str
+                       else if arg isa ATypeExpr and not id.chars.has("[") then
+                               # Class id -> HTTP method
+                               http_methods.add id
+                       else
+                               toolcontext.error(nat.location,
+                                       "Syntax Error: `restful` expects String literals or ids as arguments.")
+                               return
+                       end
+               end
+
                var mpropdef = node.mpropdef
                if mpropdef == null then return
 
@@ -61,6 +79,9 @@ private class RestfulPhase
                var mclass = mclassdef.mclass
                mclass.restful_methods.add mproperty
                restful_classes.add mclass
+
+               if http_resources.not_empty then mproperty.restful_resources = http_resources
+               mproperty.restful_verbs = http_methods
        end
 end
 
@@ -70,6 +91,14 @@ redef class MClass
        private var restful_methods = new Array[MMethod]
 end
 
+redef class MMethod
+       # HTTP access methods, e.g. `GET, POST, PUT or DELETE`
+       private var restful_verbs = new Array[String] is lazy
+
+       # Associated resources within an action, e.g. `foo` in `http://localhost/foo?arg=bar`
+       private var restful_resources: Array[String] = [name] is lazy
+end
+
 redef class ToolContext
        # Generate serialization and deserialization methods on `auto_serializable` annotated classes.
        var restful_phase: Phase = new RestfulPhase(self, [modelize_class_phase])
@@ -161,6 +190,7 @@ else
 end
 
 var nit_module = new NitModule(module_name)
+nit_module.annotations.add """no_warning("parentheses")"""
 nit_module.header = """
 # This file is generated by nitrestful
 # Do not modify, instead refine the generated services.
@@ -197,9 +227,25 @@ redef class {{{mclass}}}
                t.add "         "
                if i != 0 then t.add "else "
 
-               t.add """if resource == "{{{method.name}}}" then
+               # Condition to select this method from a request
+               var conds = new Array[String]
+
+               # Name of the resource from the method or as renamed
+               var resource_conds = new Array[String]
+               for resource in method.restful_resources do resource_conds.add "resource == \"{resource}\""
+               conds.add "(" + resource_conds.join(" or ") + ")"
+
+               # HTTP methods/verbs
+               if method.restful_verbs.not_empty then
+                       var method_conds = new Array[String]
+                       for meth in method.restful_verbs do method_conds.add "request.method == \"{meth}\""
+                       conds.add "(" + method_conds.join(" or ") + ")"
+               end
+
+               t.add """if {{{conds.join(" and ")}}} then
 """
 
+               # Extract the arguments from the request for the method call
                var args = new Array[String]
                var isas = new Array[String]
                for param in msig.mparameters do