X-Git-Url: http://nitlanguage.org diff --git a/src/nitrestful.nit b/src/nitrestful.nit index 22ffd1d..a4005d0 100644 --- a/src/nitrestful.nit +++ b/src/nitrestful.nit @@ -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. @@ -182,11 +212,11 @@ for mclass in phase.restful_classes do redef class {{{mclass}}} redef fun answer(request, truncated_uri) do - var verbs = truncated_uri.split("/") - if verbs.not_empty and verbs.first.is_empty then verbs.shift + var resources = truncated_uri.split("/") + if resources.not_empty and resources.first.is_empty then resources.shift - if verbs.length != 1 then return super - var verb = verbs.first + if resources.length != 1 then return super + var resource = resources.first """ var methods = mclass.restful_methods @@ -197,9 +227,25 @@ redef class {{{mclass}}} t.add " " if i != 0 then t.add "else " - t.add """if verb == "{{{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