=encoding UTF-8

=head1 NAME

OpenResty::Spec::REST - OpenResty REST Service Specification [draft]

=head1 AUTHOR

Agent Zhang (agentzh) <agentzh@yahoo.cn>

=head1 VERSION

    CREATED:            Nov 19, 2007
    LAST MODIFIED:      Feb 28, 2008
    VERSION:            1.00

=head1 LICENSE

  Copyright (c)  2007, 2008  Yahoo! China, Alibaba Inc.
  Permission is granted to copy, distribute and/or modify this document
  under the terms of the GNU Free Documentation License, Version 1.2
  or any later version published by the Free Software Foundation;
  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
  Texts. A copy of the license can be found at

    http://www.gnu.org/licenses/fdl.html

=head1 DESCRIPTION

This document defines the REST API for the OpenResty protocol, an web service interface to relational databases.

=head1 Login

=head2 Anonymous login

=head2 Login by password

=head2 Per-request-login

=head2 Login by captchas

=head1 Models

=head2 Operations on the model list

=head2 Operations on a model

=head2 Operations on a model column

=head2 Operations on model rows

=head1 Views

=head2 Operations on the view list

=head2 Operations on a view

=head2 Operations on a view param

=head2 Invoking a view

=head1 Actions

=head2 Operations on the action list

=head2 Operations on an action

=head2 Operations on an action param

=head2 Invoking an action

=head1 Roles

Roles are first-order objects in OpenResty, just as models, views, and actions. Roles have very similar interface to models, in particular. You'll notice the strong parallels between these two.

=head2 Operations on the role list

=head3 Read all the existing roles

    GET /=/role

The server returns a list of hashes for all the roles available in the account. Each hash corresponds to a role, containing the fields C<src>, C<name>, and C<description>. A sample response is given below:

  [
    {"src":"/=/role/Admin","name":"Admin","description":"Administrator"},
    {"src":"/=/role/Public","name":"Public","description":"Anonymous"},
    {"src":"/=/role/Newposter","name":"Newposter","description":"Comment poster"}
  ]

Note that built-in roles C<Admin> and C<Public> are reserved and will always get shown here.

=head3 Delete all the roles

    DELETE /=/role

Note that built-in roles C<Admin> and C<Public> will always be skipped. A typical server response is

    {"success":1,"warning":"Predefined roles skipped."}

=head2 Operations on a role

=head3 Create a role

    POST /=/role/~
    {
        name:        <role_name>,
        description: <role_description>,
        login:       <login_method>,
        password:    <password>,
    }

C<< <login_method> >> can be one of the following: C<anonymous>, C<password>, and C<captcha>. See the L</Login> section for more information regarding these different login methods.

The C<password> field in the JSON body for creating a new role can only appear when the C<login> field is of the value C<"password">.

=head3 Read a role's meta info

    GET /=/role/<role_name>

A typical response from the server is

    {
        "columns":[
            {"name":"id","label":Rule ID"","type":"serial"}
            {"name":"method","label":"HTTP method","type":"text"},
            {"name":"url","label":"Resource","type":"text"}
        ],
        "name":"Poster",
        "description":"My Poster Role",
        "login":"password"
    }

Note that the C<password> field won't get shown even if the C<login> field is "C<password>".

=head3 Update a role's meta info

Update some properties (C<name>, C<login>, C<password>, and etc.) for role C<< <role_name> >>:

    PUT /=/role/<role_name>
    { <key>:<new_value>, ... }

The following example

    PUT /=/role/Poster
    { name: "NewPoster", password: 5906438 }

changes the name of the C<Poster> role to C<NewPoster> I<and> also changes its password to C<5906438>.

=head3 Delete a role

Delete a role named C<< <role_name> >>:

    DELETE /=/role/<role_name>

For instance,

    DELETE /=/role/Poster

removes the C<Poster> role (as well as its associative ACL rules) completely.

=head2 Operations on a role's access rules

One can manipulate a role's ACL rules with the same interface as model rows. Every role can be considered a special model with three columns, C<id>, C<method> and C<url>.

=head2 Insert new ACL rules

One can insert one rule at a time:

    POST /=/role/<role_name>/~/~
    { method: <HTTP_method_allowed>, url: <url_pattern_allowed> }

or insert multiple rules in a single request:


    POST /=/role/<role_name>/~/~
    [
        { method: <HTTP_method_allowed>, url: <url_allowed> },
        ...
    ]

Here is an example:

    POST /=/role/Public/~/~
    [
        {"method":"POST","url":"/=/model/~"},
        {"method":"GET","url":"/=/model/A/~/~"},
        {"method":"DELETE","url":"/=/model/A/id/~"}
    ]

This request inserts 3 ACL rules for the C<Public> role. Tild C<~> is a match-any wildcard. And at least the following requests are allowed for the C<Public> role:

    POST /=/model/~
    POST /=/model/Moose
    GET /=/model/A/id/3
    GET /=/model/A/~/~
    DELETE /=/model/A/id/2
    DELETE /=/model/A/id/52

=head2 Query existing ACL rules

One can obtain all the ACL rules by using

    GET /=/role/<role_name>/~/~

or limit the rules by a rule column

    GET /=/role/<role_name>/<column>/<value>

which only returns the rules with column C<column> equal to C<value>.

=head2 Update existing ACL rules

=head2 Delete existing ACL rules