Merge pull request #21 from openwhisk/doc

Update readme and documentation
diff --git a/README.md b/README.md
index 02ab4c9..943910f 100644
--- a/README.md
+++ b/README.md
@@ -7,18 +7,16 @@
 This project is currently considered pre-alpha stage, and should not be used in production. Large swaths of code or APIs may change without notice.
 
 
-Table of Contents
-=================
+## Table of Contents
 
 * [Quick Start](#quick-start)
-* [API](#api)
-  * [Resources](#resources)
-  * [Subscriptions](#subscriptions)
+* [Routes](#routes)
 * [Developer Guide](#developer-guide)
+  * [Running locally](#running-locally)
+  * [Testing](#testing)
 
 
-Quick Start
-===========
+## Quick Start
 
 ```
 docker run -p 80:80 -p <managedurl_port>:8080 -p 9000:9000 \
@@ -34,218 +32,13 @@
 
 On startup, the API Gateway looks for pre-existing resources in redis, whose keys are defined as `resources:<namespace>:<resource>`, and creates nginx conf files associated with those resources. Then, it listens for any resource key changes in redis and updates nginx conf files appropriately. These conf files are stored in the running docker container at `/etc/api-gateway/managed_confs/<namespace>/<resource>.conf`.
 
-
-API
-==============
-The following endpoints are exposed to port 9000.
-
-## Resources
-#### PUT /resources/{namespace}/{url-encoded-resource}
-Create/update and expose a new resource on the gateway associated with a namespace and a url-encoded resource, with the implementation matching the passed values.
-
-_body:_
-```
-{
-  "gatewayMethod": *(string) The method that you would like your newly exposed API to listen on.
-  "backendURL": *(string) The fully qualified URL that you would like your invoke operation to target.
-  "backendMethod": (string) The method that you would like the invoke operation to use. If none is supplied, the gatewayMethod will be used.
-  "policies": *(array) A list of policy objects that will be applied during the execution of your resource.
-  "security": (object) An optional json object defining security policies (e.g. {"type": "apikey"} )
-}
-```
-
-_Returns:_
-```
-{
-  "managedUrl": (string) The URL at which you can invoke your newly created resource.
-}
-```
-
-####Policies
-The currently supported policies are: `reqMapping`, `rateLimit`.
-
-#####rateLimit:
-_interval:_ the time interval that the rate is applied to.  
-_rate:_ the number of calls allowed per interval of time.  
-_scope:_ `api`, `tenant`, `resource`.  
-_subscription:_ `true`, `false`.  
-If subscription is `true`, the rateLimit applies to each user with a vaild subscription.  
-If subscription is `false`, the rateLimit applies the collective usage from all users.  
-```
-  "interval":60,
-  "rate":10,
-  "scope":"api"
-  "subscription": "false"
-```
-This will set a rateLimit ratio of 10 calls per 60 second, at an API level.  
-This rateLimit is shared across all users (subescription:false).  
-
-#####reqMapping:
-Supported actions: `remove`, `default`, `insert`, `transform`.  
-Supported locations: `body`, `path`, `header`, `query`.  
-
-_remove:_
-```
-{
-   "action":"remove",
-   "from":{
-      "value":"<password>"
-      "location":"body"
-   }
-}
-```
-This will remove the `password` field from the body of the incoming request, so it's not passed to the backendURL  
-
-_default:_  
-Only `body`, `header`, `query` parameters can have default values.  
-```
-{
-   "action":"default",
-   "from":{
-      "value":"BASIC XXX"
-   },
-   "to":{
-      "name":"Authorization",
-      "location":"header"
-   }
-}
-```
-This will assign the value of `BASIC XXX` to a `header` called `Authorization` but only if the value is not already set.  
-
-_insert:_
-```
-{
-   "action":"insert",
-   "from":{
-      "value":"application/json"
-   },
-   "to":{
-      "name":"Content-type",
-      "location":"header"
-   }
-}
-```
-This will insert the value of `application/json` into a `header` named `Content-type` on the backend request
-
-_transform:_
-```
-{
-   "action":"transform",
-   "from":{
-      "name":"*",
-      "location":"query"
-   },
-   "to":{
-      "name":"*",
-      "location":"body"
-   }
-}
-```
-This will transform all incoming `query` parameters into `body` parameters in the outgoing request to the backendURL.  
-Where `*` is a wild card, or you can use the variable name.  
-
-_Path Parameter Mappings:_  
-To map a path parameter from the incoming Url to a path parameter on the backend Url, you will need to wrap brackets `{}` around the path parameter on the incoming Url as well as the backend Url, for example:  
-`IP:Port/resources/tenant_id/serverless/{myAction}/restified`
-```
-"backendURL":"https://openwhisk.stage1.ng.bluemix.net/api/v1/namespaces/APIC-Whisk_test/actions/{ACTION}?blocking=true&result=true",
-"policies":
-  [{
-    "type": "reqMapping",
-    "value": [{
-        "action": "transform",
-        "from": {
-          "name": "myAction",
-          "location": "path"
-        },
-        "to": {
-          "name": "ACTION",
-          "location": "path"
-        }
-      }]
-  }]
-```
-If a path is then invoked on `/serverless/Hello World/restified`, then the value from `{myAction}`, which is `Hello World`, will be assigned to the variable `ACTION` on the backend path.
-
-####Security
-Supported types: `apiKey`.  
-_scope:_ `api`, `tenant`, `resource`.  
-_header:_ _(optional)_ custom name of auth header (default is x-api-key)  
-
-```
-"security": {
-        "type":"apiKey",
-        "scope":"api",
-        "header":"<MyCustomAuthHeader>"
-    }
-```
-This will add security of an `apiKey`, at the API level, and uses the header call `myCustomAuthHeader`.  
-NOTE: Security added at the Tenant level will affect all APIs and resources under that Tenant. Likewise, security added at the API level will affect all resources under that API.
-
-#### GET /resources/{namespace}/{url-encoded-resource}
-Get the specified resource and return the managed url.
-
-_Returns:_
-```
-{
-  "managedUrl": (string) The URL at which you can invoke the resource.
-}
-```
-
-#### DELETE /resources/{namespace}/{url-encoded-resource}
-Delete the specified resource from redis and delete the corresponding conf file.
-
-_Returns:_
-```
-Resource deleted.
-```
-
-#### GET /subscribe
-This is called automatically on gateway startup. It subscribes to resource key changes in redis and creates/updates the necessary nginx conf files.
+## Routes
+See [here](doc/routes.md) for the management interface for creating tenants/APIs. For detailed API policy definitions, see [here](doc/policies.md).
 
 
-## Subscriptions
-#### PUT /subscriptions
-Add/update an api key for the specified tenant, resource, or api.
+## Developer Guide
 
-_body:_
-```
-{
-  "key": *(string) The api key to store to redis.
-  "scope": *(string) The scope to use the api key. "tenant", "resource", or "api".
-  "tenant": *(string) Tenant guid.
-  "resource": (string) Resource path. Required if scope is "resource".
-  "api": (string) API Guid. Required if scope is "API".
-}
-```
-
-_Returns:_
-```
-Subscription created.
-```
-
-#### DELETE /subscriptions
-Delete an api key associated with the specified tenant, resource or api.
-
-_body:_
-```
-{
-  "key": *(string) The api key to delete.
-  "scope": *(string) The scope to use the api key. "tenant", "resource", or "api".
-  "tenant": *(string) Tenant guid.
-  "resource": (string) Resource path. Required if scope is "resource".
-  "api": (string) API Guid. Required if scope is "API".
-}
-```
-
-_Returns:_
-```
-Subscription deleted.
-```
-
-
-Developer Guide
-================
+### Running locally
 
  To build the docker image locally use:
  ```
@@ -264,7 +57,7 @@
     API-Platform is running!
  ```
  
-##Testing
+### Testing
 
  Unit tests can be found in the `api-gateway-config/tests/spec` directory.
 
diff --git a/doc/policies.md b/doc/policies.md
new file mode 100644
index 0000000..6317547
--- /dev/null
+++ b/doc/policies.md
@@ -0,0 +1,124 @@
+Policies
+==============
+The following defines the different policies that can be used when creating an API. The currently supported policies are:
+`reqMapping`, `rateLimit`.
+
+
+###rateLimit:
+_interval:_ the time interval that the rate is applied to.  
+_rate:_ the number of calls allowed per interval of time.  
+_scope:_ `api`, `tenant`, `resource`.  
+_subscription:_ `true`, `false`.  
+If subscription is `true`, the rateLimit applies to each user with a vaild subscription.  
+If subscription is `false`, the rateLimit applies the collective usage from all users.  
+```
+  "interval":60,
+  "rate":10,
+  "scope":"api"
+  "subscription": "false"
+```
+This will set a rateLimit ratio of 10 calls per 60 second, at an API level.  
+This rateLimit is shared across all users (subescription:false).  
+
+###reqMapping:
+Supported actions: `remove`, `default`, `insert`, `transform`.  
+Supported locations: `body`, `path`, `header`, `query`.  
+
+_remove:_
+```
+{
+   "action":"remove",
+   "from":{
+      "value":"<password>"
+      "location":"body"
+   }
+}
+```
+This will remove the `password` field from the body of the incoming request, so it's not passed to the backendURL  
+
+_default:_  
+Only `body`, `header`, `query` parameters can have default values.  
+```
+{
+   "action":"default",
+   "from":{
+      "value":"BASIC XXX"
+   },
+   "to":{
+      "name":"Authorization",
+      "location":"header"
+   }
+}
+```
+This will assign the value of `BASIC XXX` to a `header` called `Authorization` but only if the value is not already set.  
+
+_insert:_
+```
+{
+   "action":"insert",
+   "from":{
+      "value":"application/json"
+   },
+   "to":{
+      "name":"Content-type",
+      "location":"header"
+   }
+}
+```
+This will insert the value of `application/json` into a `header` named `Content-type` on the backend request
+
+_transform:_
+```
+{
+   "action":"transform",
+   "from":{
+      "name":"*",
+      "location":"query"
+   },
+   "to":{
+      "name":"*",
+      "location":"body"
+   }
+}
+```
+This will transform all incoming `query` parameters into `body` parameters in the outgoing request to the backendURL.  
+Where `*` is a wild card, or you can use the variable name.  
+
+_Path Parameter Mappings:_  
+To map a path parameter from the incoming Url to a path parameter on the backend Url, you will need to wrap brackets `{}` around the path parameter on the incoming Url as well as the backend Url, for example:  
+`IP:Port/resources/tenant_id/serverless/{myAction}/restified`
+```
+"backendURL":"https://openwhisk.stage1.ng.bluemix.net/api/v1/namespaces/APIC-Whisk_test/actions/{ACTION}?blocking=true&result=true",
+"policies":
+  [{
+    "type": "reqMapping",
+    "value": [{
+        "action": "transform",
+        "from": {
+          "name": "myAction",
+          "location": "path"
+        },
+        "to": {
+          "name": "ACTION",
+          "location": "path"
+        }
+      }]
+  }]
+```
+If a path is then invoked on `/serverless/Hello World/restified`, then the value from `{myAction}`, which is `Hello World`, will be assigned to the variable `ACTION` on the backend path.
+
+
+##Security
+Supported types: `apiKey`.  
+_scope:_ `api`, `tenant`, `resource`.  
+_header:_ _(optional)_ custom name of auth header (default is x-api-key)  
+
+```
+"security": {
+        "type":"apiKey",
+        "scope":"api",
+        "header":"<MyCustomAuthHeader>"
+    }
+```
+This will add security of an `apiKey`, at the API level, and uses the header call `myCustomAuthHeader`.  
+NOTE: Security added at the Tenant level will affect all APIs and resources under that Tenant. Likewise, security added at the API level will affect all resources under that API.
\ No newline at end of file
diff --git a/doc/routes.md b/doc/routes.md
new file mode 100644
index 0000000..74ac384
--- /dev/null
+++ b/doc/routes.md
@@ -0,0 +1,276 @@
+Routes
+==============
+The following defines the interface for managing APIs and Tenants. These endpoints are exposed to port 9000.
+
+## APIs
+
+### PUT /apis
+Create a new API. Note that you should first create a tenant and obtain its `tenantId`. For API policy definitions, see [here](policies.md).
+
+_body_:
+```
+{
+  "name": *(string),
+  "basePath": *(string),
+  "tenantId": *(string),
+  "resources": {
+    "path": {
+      "operations": {
+        "get": {
+          "backendMethod": *(string),
+          "backendUrl": *(string),
+          "policies": [
+            {
+              "type": *(string),
+              "value": {}
+            }
+          ]
+        },
+        ...
+      }
+    }
+  }
+}
+```
+
+_returns:_
+```
+{
+  "id": (string),
+  "name": (string),
+  "basePath": (string),
+  "tenantId": (string),
+  "resources": {
+   ...
+  }
+}
+```
+
+### PUT /apis/{id}
+Update attributes for a given API.
+
+_body_:
+```
+{
+  "name": *(string),
+  "basePath": *(string),
+  "tenantId": *(string),
+  "resources": {
+    "path": {
+      "operations": {
+        "get": {
+          "backendMethod": *(string),
+          "backendUrl": *(string),
+          "policies": [
+            {
+              "type": *(string),
+              "value": {}
+            }
+          ]
+        },
+        ...
+      }
+    }
+  }
+}
+```
+
+_returns:_
+```
+{
+  "id": (string),
+  "name": (string),
+  "basePath": (string),
+  "tenantId": (string),
+  "resources": {
+   ...
+  }
+}
+```
+
+### GET /apis
+Find all instances of APIs added to the gateway.
+
+_returns:_
+```
+[
+  {
+    "id": (string),
+    "name": (string),
+    "basePath": (string),
+    "tenantId": (string),
+    "resources": {
+     ...
+    }
+  }
+]
+```
+
+### GET /apis/{id}
+Find an API by its id.
+
+_returns:_
+```
+{
+  "id": (string),
+  "name": (string),
+  "basePath": (string),
+  "tenantId": (string),
+  "resources": {
+   ...
+  }
+}
+```
+
+### GET /apis/{id}/tenant
+Find the tenant associated with this API.
+
+_returns:_
+```
+{
+ "id": (string),
+ "namespace" (string),
+ "instance" (string)
+}
+```
+
+
+### DELETE /apis/{id}
+Delete the API
+
+_returns:_
+```
+{}
+```
+
+## Tenants
+
+### PUT /tenants
+Create a new tenant.
+
+_body:_
+```
+{
+ "namespace": *(string),
+ "instance": *(string)
+}
+```
+_returns:_
+```
+{
+ "id": (string),
+ "namespace" (string),
+ "instance" (string)
+}
+```
+
+### PUT /tenants/{id}
+Update attributes for a given tenant.
+
+_body:_
+```
+{
+ "namespace": *(string),
+ "instance": *(string)
+}
+```
+_returns:_
+```
+{
+ "id": (string),
+ "namespace" (string),
+ "instance" (string)
+}
+```
+
+### GET /tenants
+Find all instances of tenants added to the gateway.
+
+_returns:_
+```
+[
+ {
+  "id": (string),
+  "namespace" (string),
+  "instance" (string)
+ }
+]
+```
+
+### GET /tenants/{id}
+Find a tenant by its id.
+
+_returns:_
+```
+{
+ "id": (string),
+ "namespace" (string),
+ "instance" (string)
+}
+```
+
+### DELETE /tenants/{id}
+Delete the tenant.
+
+_returns:_
+```
+{}
+```
+
+### GET /tenants/{id}/apis
+Get all APIs for the given tenant.
+
+_returns:_
+```
+[
+  {
+    "id": (string),
+    "name": (string),
+    "basePath": (string),
+    "tenantId": (string),
+    "resources": {
+     ...
+    }
+  }
+]
+```
+
+
+## Subscriptions
+### PUT /subscriptions
+Add/update an api key for the specified tenant, resource, or api.
+
+_body:_
+```
+{
+  "key": *(string) The api key to store to redis.
+  "scope": *(string) The scope to use the api key. "tenant", "resource", or "api".
+  "tenant": *(string) Tenant guid.
+  "resource": (string) Resource path. Required if scope is "resource".
+  "api": (string) API Guid. Required if scope is "API".
+}
+```
+
+_Returns:_
+```
+Subscription created.
+```
+
+### DELETE /subscriptions
+Delete an api key associated with the specified tenant, resource or api.
+
+_body:_
+```
+{
+  "key": *(string) The api key to delete.
+  "scope": *(string) The scope to use the api key. "tenant", "resource", or "api".
+  "tenant": *(string) Tenant guid.
+  "resource": (string) Resource path. Required if scope is "resource".
+  "api": (string) API Guid. Required if scope is "API".
+}
+```
+
+_Returns:_
+```
+Subscription deleted.
+```
\ No newline at end of file