Support module for the nitrestful tool and the restful annotation

The restful annotation is applied on a method to assign it to an HTTP resource. The restful method must be a property of a subclass of RestfulAction and return an HTTPResponse. Once an instance of the class is assigned to a route, the method can be invoked as a resource under that route. The returned HTTPResponse will be sent back to the client.

The arguments of the method must be deserializable. So use simple data types like String, Int, Float, etc. or any other Serializable class. The method is invoked only if all the arguments are correctly passed in the JSON format by the HTTP client. There is one exception, String arguments are returned as is, they don't need the surrounding "". If an argument is missing or there a format error, the answer method responds to the request. Arguments that are nullable are optional, if they are missing null is passed to the restful method.

The annotation accepts three kinds of arguments, in any order:

  • String literals rename or add an alias for the HTTP resource. By default, the name of the HTTP resource is the name of the restful method. The first string literal replaces the default name, while additional string literals add aliases.

  • Ids such as GET, POST, PUT and DELETE restrict which HTTP methods are accepted. By default, all HTTP methods are accepted.

  • The async keyword triggers executing calls to this service asynchronously by the thread_pool attribute of the RestfulAction. By default, each call are executed on the same thread in a FIFO order.

See the example at lib/nitcorn/examples/restful_annot.nit or a real world use case at contrib/benitlux/src/server/benitlux_controller.nit.

The restful annotation is implemented by then nitrestful tool. To compile a module (my_module.nit) that uses the restful annotation:

  • Run nitrestful my_module.nit to produce my_module_rest.nit
  • Link my_module_rest.nit at compilation: nitc my_module.nit -m my_module_rest.nit.

Introduced classes

class RestfulAction

nitcorn :: RestfulAction

Action with restful methods
abstract class RestfulTask

nitcorn :: RestfulTask

Thread dedicated to a single request

All class definitions

class RestfulAction

nitcorn $ RestfulAction

Action with restful methods
abstract class RestfulTask

nitcorn $ RestfulTask

Thread dedicated to a single request
package_diagram nitcorn::restful restful nitcorn nitcorn nitcorn::restful->nitcorn json json nitcorn::restful->json pthreads::threadpool threadpool nitcorn::restful->pthreads::threadpool parser_base parser_base json->parser_base serialization serialization json->serialization pthreads::concurrent_collections concurrent_collections pthreads::threadpool->pthreads::concurrent_collections ...nitcorn ... ...nitcorn->nitcorn ...parser_base ... ...parser_base->parser_base ...serialization ... ...serialization->serialization ...pthreads::concurrent_collections ... ...pthreads::concurrent_collections->pthreads::concurrent_collections nitcorn::restful_annot restful_annot nitcorn::restful_annot->nitcorn::restful nitcorn::test_restful_annot test_restful_annot nitcorn::test_restful_annot->nitcorn::restful_annot nitcorn::test_restful_annot... ... nitcorn::test_restful_annot...->nitcorn::test_restful_annot

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module array

core :: array

This module introduces the standard array structure.
module base64

base64 :: base64

Offers the base 64 encoding and decoding algorithms
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module caching

serialization :: caching

Services for caching serialization engines
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module concurrent_collections

pthreads :: concurrent_collections

Introduces thread-safe concurrent collections
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module engine_tools

serialization :: engine_tools

Advanced services for serialization engines
module environ

core :: environ

Access to the environment variables of the process
module error

json :: error

Intro JsonParseError which is exposed by all JSON reading APIs
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module file

core :: file

File manipulations (create, read, write, etc.)
module file_server

nitcorn :: file_server

Provides the FileServer action, which is a standard and minimal file server
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module http_errors

nitcorn :: http_errors

Offers ErrorTemplate to display error pages
module http_request

nitcorn :: http_request

Provides the HttpRequest class and services to create it
module http_request_buffer

nitcorn :: http_request_buffer

Http request parsing for buffered inputs.
module http_response

nitcorn :: http_response

Provides the HttpResponse class and http_status_codes
module inspect

serialization :: inspect

Refine Serializable::inspect to show more useful information
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module libevent

libevent :: libevent

Low-level wrapper around the libevent library to manage events on file descriptors
module list

core :: list

This module handle double linked lists
module math

core :: math

Mathematical operations
module md5

md5 :: md5

Native MD5 digest implementation as Text::md5
module media_types

nitcorn :: media_types

Services to identify Internet media types (or MIME types, Content-types)
module meta

meta :: meta

Simple user-defined meta-level to manipulate types of instances as object.
module more_collections

more_collections :: more_collections

Highly specific, but useful, collections-related classes.
module native

core :: native

Native structures for text and bytes
module numeric

core :: numeric

Advanced services for Numeric types
module parser_base

parser_base :: parser_base

Simple base for hand-made parsers of all kinds
module poset

poset :: poset

Pre order sets and partial order set (ie hierarchies)
module protocol

core :: protocol

module pthreads

pthreads :: pthreads

Main POSIX threads support and intro the classes Thread, Mutex and Barrier
module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module reactor

nitcorn :: reactor

Core of the nitcorn project, provides HttpFactory and Action
module ropes

core :: ropes

Tree-based representation of a String.
module safe

serialization :: safe

Services for safer deserialization engines
module serialization

serialization :: serialization

General serialization services
module serialization_core

serialization :: serialization_core

Abstract services to serialize Nit objects to different formats
module serialization_read

json :: serialization_read

Services to read JSON: deserialize_json and JsonDeserializer
module serialization_write

json :: serialization_write

Services to write Nit objects to JSON strings: serialize_to_json and JsonSerializer
module server_config

nitcorn :: server_config

Classes and services to configure the server
module sessions

nitcorn :: sessions

Automated session management
module signal_handler

nitcorn :: signal_handler

Handle SIGINT and SIGTERM to close the server after all active events
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module static

json :: static

Static interface to read Nit objects from JSON strings
module stream

core :: stream

Input and output streams of characters
module template

template :: template

Basic template system
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module token

nitcorn :: token

Simple generate_token service, independent of the rest of the nitcorn framework
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O
module vararg_routes

nitcorn :: vararg_routes

Routes with parameters.

Parents

module json

json :: json

Read and write JSON formatted text using the standard serialization services
module nitcorn

nitcorn :: nitcorn

The nitcorn Web server framework creates server-side Web apps in Nit
module threadpool

pthreads :: threadpool

Introduces a minimal ThreadPool implementation using Tasks

Children

module restful_annot

nitcorn :: restful_annot

Example for the restful annotation documented at lib/nitcorn/restful.nit

Descendants

# Support module for the `nitrestful` tool and the `restful` annotation
#
# The `restful` annotation is applied on a method to assign it to an HTTP resource.
# The `restful` method must be a property of a subclass of `RestfulAction` and
# return an `HTTPResponse`.
# Once an instance of the class is assigned to a route, the method
# can be invoked as a resource under that route.
# The returned `HTTPResponse` will be sent back to the client.
#
# The arguments of the method must be deserializable.
# So use simple data types like `String`, `Int`, `Float`, etc.
# or any other `Serializable` class.
# The method is invoked only if all the arguments are correctly passed
# in the JSON format by the HTTP client.
# There is one exception, `String` arguments are returned as is,
# they don't need the surrounding `""`.
# If an argument is missing or there a format error, the `answer` method responds to the request.
# Arguments that are `nullable` are optional,
# if they are missing `null` is passed to the `restful` method.
#
# The annotation accepts three kinds of arguments, in any order:
#
# * String literals rename or add an alias for the HTTP resource.
#   By default, the name of the HTTP resource is the name of the `restful` method.
#   The first string literal replaces the default name,
#   while additional string literals add aliases.
#
# * Ids such as `GET`, `POST`, `PUT` and `DELETE` restrict which HTTP methods
#   are accepted. By default, all HTTP methods are accepted.
#
# * The `async` keyword triggers executing calls to this service asynchronously
#   by the `thread_pool` attribute of the `RestfulAction`.
#   By default, each call are executed on the same thread in a FIFO order.
#
# See the example at `lib/nitcorn/examples/restful_annot.nit` or
# a real world use case at `contrib/benitlux/src/server/benitlux_controller.nit`.
#
# The `restful` annotation is implemented by then `nitrestful` tool.
# To compile a module (`my_module.nit`) that uses the `restful` annotation:
#
# * Run `nitrestful my_module.nit` to produce `my_module_rest.nit`
# * Link `my_module_rest.nit` at compilation: `nitc my_module.nit -m my_module_rest.nit`.
module restful is new_annotation(restful)

import nitcorn
private import json
import pthreads::threadpool

# Action with `restful` methods
class RestfulAction
	super Action

	redef fun answer(request, truncated_uri) do return new HttpResponse(400)

	# Deserialize `val` from JSON for a parameter typed by `static_type`
	#
	# Accepts `nullable String` for convenience, but returns `null` when `val == null`.
	#
	# This method is called by the code generated by `nitrestful`.
	# It can be specialized to customize its behavior.
	protected fun deserialize_arg(val: nullable String, static_type: String): nullable Object
	do
		if val == null then return null

		var deserializer = new JsonDeserializer(val)
		var obj = deserializer.deserialize(static_type)

		if deserializer.errors.not_empty then
			print_error deserializer.errors.join("\n")
			return null
		end

		return obj
	end

	# Thread pool used by methods annotated with `restful(async)`
	var thread_pool = new ThreadPool is writable
end

# Thread dedicated to a single `request`
abstract class RestfulTask
	super Task

	# Type of `action`
	type A: RestfulAction

	# Receiver action
	var action: A

	# Request that created this thread
	var request: HttpRequest

	# Server handling the `request`
	var http_server: HttpServer

	# Indirection to the real method in `action`
	protected fun indirect_restful_method: HttpResponse is abstract

	redef fun main
	do
		var response = indirect_restful_method
		http_server.respond response
		http_server.close
	end
end
lib/nitcorn/restful.nit:15,1--119,3