Alpine Configurator HTTP Protocol
=================================

Load JavaScript client:
req: GET /

Log in:
req: POST /login
     - body is a JSON object with username and password attributes
resp headers:
     - X-AConf-Auth-Token: authentication token, use in the header of
       subsequent requests
     - X-AConf-Save-Required: if set to 1, an explicit request is
       required to save the changed files persistently

Log out:
req: DELETE /login
     X-AConf-Auth-Token: <token>

Save configuration files persistently (lbu commit):
req: POST /save

Start transaction:
req: POST /transaction
resp: txn ID (in header as X-AConf-Transaction-ID)
      - use X-AConf-Transaction-ID in the header of any subsequent
      	request to process it in the transaction's context
      - nested transactions can be started by using it in a subsequent
      	start transaction request

Commit transaction:
req: PUT /transaction
     X-AConf-Transaction-ID: <txn_id>

Abort transaction:
req: DELETE /transaction
     X-AConf-Transaction-ID: <txn_id>

Get object:
req: GET /config/<obj_path>
resp: JSON object, with the following attributes:
      data: JSON serialization of object
      	    - primitive types as JSON primitives
	    - binary data encoded as data URIs
      	    - references as path names (relative to scope)
      	    - models as JSON objects with members as attributes:
      	      - primitive members as JSON primitives
      	      - binary, reference, model, collection, list, and set
	      	members as path names
      	    - collections, lists, and sets as JSON arrays with members
	      as attributes (as for models)
      meta: JSON object, with the following attributes
      	    - name (last component of path name)
      	    - ui-name (shown to user)
      	    - description (optional help text)
	    - type (e.g. model, collection, list, set, reference,
	      string, number, boolean, binary)
      	    - widget (name of client-side JS module used to display
	      the data)
	    - detail: boolean indicating whether the value should be
	      shown only in the object-specific detailed view
	    - editable (boolean)
	    - condition: if present, the field is relevant only when
	      other fields are set according to this object
      	    - required (boolean)
	    - default
      	    - max-length
      	    - choices: optional array of allowed values, which are
	      objects with the following attributes:
	      - value
	      - ui-value (user-friendly version)
	      - ref (absolute path to the referred object, not defined
	      	if refers to a primitive value)
	    - dynamic: boolean indicating whether choices may change
	      based on other fields
      	    - fields (model only): array of field metadata JSON
	      objects
	    - members (collections, lists, and sets only): metadata
	      for members (JSON object)
	    - ui-member (collections, lists, and sets only): singular
	      noun describing members (shown to user)
	    - removable (collections, lists, and sets only): list of
	      removable members
      	    - scope (references only): subtree where the reference can
	      refer to

Create/update object:
req: PUT /config/<obj_path>
     - body shall contain the object serialized as the data attribute
       in GET responses
     - undefined model attributes are deleted

Add object to a list:
req: POST /config/<list_path>
     - body is a JSON object with the following attributes:
       data: object to be added, serialized as in GET responses
       index: position, defaults to the end of the list

Delete object:
req: DELETE /config/<obj_path>

Add member to a set:
req: POST /config/<set_path>
     - body shall contain a JSON primitive

Delete set member:
req: DELETE /config/<set_path>/<member>

Invoke object-specific action (not yet supported by server):
req: POST /config/<obj_path>/<action>
     - arguments passed as a JSON array in body; serialization as in
       GET responses
resp: action-specific JSON
      - for time-consuming actions, can return multiple JSON
      	documents, each containing a status update

Get metadata (for a potentially non-existent object):
req: GET /meta/<path>
resp: as the meta attribute in get object response


Use of HTTP status codes:

2xx Success

400 Bad request
    resp: plain text error message

401 Authentication error

403 Forbidden

404 Not found

405 Method not allowed

409 Concurrent modification
    resp: JSON list of objects modified by a concurrent transaction

422 Semantic error
    resp: JSON object mapping paths to object-specific lists of
    	  validation error messages

500 Server error
