1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Example for the `restful` annotation documented at `lib/nitcorn/restful.nit`
16 module restful_annot
is example
18 import nitcorn
::restful
19 import nitcorn
::pthreads
21 # An action root to its `restful` methods
25 # Method answering requests such as `foo?s=some_string&i=42&b=true`
27 # By default, the name of the HTTP resource is the name of the method.
28 # Responds to all HTTP methods, including GET, POST, PUT and DELETE.
30 # All arguments are deserialized from a JSON format,
31 # except for strings that are used as is.
32 fun foo
(s
: String, i
: Int, b
: Bool): HttpResponse
34 var resp
= new HttpResponse(200)
35 resp
.body
= "foo {s} {i} {b}"
39 # Method answering requests such as `api_name?s=these_arguments_are_optional`
41 # This method is available as both `api_name` and `alt_name` in HTTP.
42 # Responds only to the GET and PUT HTTP method.
43 fun bar
(s
: nullable String, i
: nullable Int, b
: nullable Bool): HttpResponse
44 is restful
("api_name", "alt_name", GET, PUT) do
46 var resp
= new HttpResponse(200)
47 resp
.body
= "bar {s or else "null"} {i or else "null"} {b or else "null"}"
51 # Asynchronous method answering requests such as `async_service?str=some_string`
53 # This method is executed by the `thread_pool` attribute of this class.
54 # Be careful when using the `async` argument to follow all the good
55 # concurrent programming pratices.
56 fun async_service
(str
: String): HttpResponse
59 # "Work" for 2 seconds
63 var resp
= new HttpResponse(200)
64 resp
.body
= "async_service {str}"
68 # Method with two complex parameters answering requests such as
69 # `complex_args?array=["a","b"]&data={"str":"asdf","more":{"str":"ASDF"}}`
71 # Collections and other classes can also be used as parameters,
72 # they will be deserialized from JSON format.
73 # By default, the JSON objects will be parsed as the type of the parameter.
74 # In the example above, the argument passed as `data` is deserialized as a `MyData`.
75 # However, you can use metadata in the JSON object to deserialize it
76 # as a subclass of `MyData`, as in this request where `data` is a `MyOtherData`:
78 # `complex_args?array=["a","b"]&data={"__class":"MyOtherData","str":"asdf","i":1234}`
80 # See the `json` package documentation for more information on JSON
81 # deserialization and the metadata values.
82 fun complex_args
(array
: Array[String], data
: MyData): HttpResponse
84 var resp
= new HttpResponse(200)
85 resp
.body
= "complex_args {array} {data}"
89 # Catch all other request
90 redef fun answer
(request
, turi
)
92 var resp
= new HttpResponse(404)
93 resp
.body
= "Fallback answer"
98 # Simple data structure for `MyAction::complex_args`
106 var more
: nullable MyData
108 redef fun to_s
do return "<MyData str:{str} more:{more or else "null"}>"
111 # Another data structure, subclass to `MyData`
119 redef fun to_s
do return "<MyOtherData str:{str} more:{more or else "null"} i:{i}>"
122 var vh
= new VirtualHost("localhost:8080")
124 # Set `rest_path` as the root for an instance of `MyAction`, so:
125 # * `MyClass::foo` is available as `localhost:8080/rest_path/foo?s=s&i=12&b=true`,
126 # * `MyClass::bar` is available as both `localhost:8080/rest_path/api_name?s=s`
127 # and `localhost:8080/rest_path/alt_name?...`.
128 # * `MyClass::async_service` is available as `localhost:8080/rest_path/async_service?str=str`
129 # * `MyClass::complex_args` is available as
130 # `localhost:8080/rest_path/complex_args?array=["a","b"]&data={"str":"asdf"}`
131 vh
.routes
.add
new Route("rest_path", new MyAction)
133 var factory
= new HttpFactory.and_libevent
134 factory
.config
.virtual_hosts
.add vh