diff --git a/docs/api/reading.md b/docs/api/reading.md
index 5cd7a39c9..ea2a4460a 100644
--- a/docs/api/reading.md
+++ b/docs/api/reading.md
@@ -20,7 +20,7 @@ GET /people
```
There are no `deeply/nested/routes`. Each route provides `OPTIONS`,
-`GET`, `POST`, `PUT`, `PATCH`, and `DELETE` verbs depending entirely
+`GET`, `POST`, `PATCH`, and `DELETE` verbs depending entirely
on database permissions.
@@ -28,9 +28,9 @@ on database permissions.
Why not provide nested routes? Many APIs allow nesting to
retrieve related information, such as /films/1/director.
- We offer a more flexible mechanism instead to embed related
- information, including many-to-many relationships. This is covered
- in the section about Embedding.
+ We offer a more flexible mechanism (inspired by GraphQL) to embed
+ related information. It can handle one-to-many and many-to-many
+ relationships. This is covered in the section about Embedding.
### Stored Procedures
@@ -47,7 +47,7 @@ POST /rpc/proc_name
PostgREST supports calling procedures with [named
arguments](http://www.postgresql.org/docs/9.4/static/sql-syntax-calling-funcs.html#SQL-SYNTAX-CALLING-FUNCS-NAMED).
-To do so include a JSON object in the request payload and each
+Include a JSON object in the request payload and each
key/value of the object will become an argument.
@@ -212,7 +212,7 @@ count total using a ```Prefer``` header as:
Prefer: count=none
```
-So the PostgREST response will be something like:
+With count suppressed the PostgREST response will look like:
```
Range-Unit: items
@@ -227,7 +227,7 @@ API you can have it embed the client within each project response.
For example,
```HTTP
-GET /projects?id=eq.1&select=id, name, clients(*)
+GET /projects?id=eq.1&select=id, name, clients{*}
```
Notice this is the same `select` keyword which is used to choose
@@ -240,7 +240,15 @@ The embedding works for 1-N, N-1, and N-N relationships. That means
you could also ask for a client and all their projects:
```HTTP
-GET /clients?id=eq.42&select=id, name, projects(*)
+GET /clients?id=eq.42&select=id, name, projects{*}
+```
+
+In the examples above we asked for all columns in the embedded resource
+but the the select query is recursive. You could for instance specify
+
+
+```HTTP
+GET /foo?select=x, y, bar{z, w, baz{*}}
```
### Response Format
@@ -265,7 +273,8 @@ For consistency's sake all these endpoints return a JSON array,
`/stories`, `/stories?genre=eq.mystery`, `/stories?id=eq.1`. They
are all filtering a bigger array. However you might want the
last one to return a single JSON object, not an array with one
-element. There is currently an open issue to enable this.
+element. To request a singular response send the header
+`Prefer: plurality=singular`.
### Data Schema
diff --git a/docs/api/writing.md b/docs/api/writing.md
index bfd847050..0c9473694 100644
--- a/docs/api/writing.md
+++ b/docs/api/writing.md
@@ -26,9 +26,13 @@ the server side.
* ❌ Cannot be cached or prefetched
* ❌ Not idempotent
-While regular insertion uses JSON to encode the value, bulk insertion
-uses CSV. Simply post to a table route with `Content-Type: text/csv`
-and include the names of the columns as the first row. For instance
+You can POST a JSON array or CSV to insert multiple rows in a single
+HTTP request. Note that using CSV requires less parsing on the server
+and is **much faster**.
+
+Example of CSV bulk insert. Simply post to a table route with
+`Content-Type: text/csv` and include the names of the columns as
+the first row. For instance
```HTTP
POST /people
@@ -41,42 +45,31 @@ An empty field (`,,`) is coerced to an empty string and the reserved
word `NULL` is mapped to the SQL null value. Note that there should
be no spaces between the column names and commas.
-The server sends a multipart response for bulk insertions. Each part
-contains a Location header with URL of each created resource.
+Example of JSON bulk insert. Send an array:
```HTTP
-Content-Type: application/json
-Location: /festival?name=eq.Venice%20Film%20Festival
-
-
---postgrest_boundary
-Content-Type: application/json
-Location: /festival?name=eq.Cannes%20Film%20Festival
+POST /people
+[
+ { "name": "J Doe", "age": 62, "height": 70 },
+ { "name": "Janus", "age": 10, "height": 55 }
+]
```
-### Upsertion
-
-* ❌ Cannot be cached or prefetched
-* ✅ Idempotent
-
-To insert or update a single row use the `PUT` verb on a properly
-filtered table url:
-
-```HTTP
-PUT /table_name?primary_key=eq.foo
-{ "col1": "value1", "col2": "value2" }
-```
-
-The request must satisfy two things. First all columns must be
-specified (because a default value might be a changing value which
-would violate idempotence). Second the URL must match the URL you
-would use to get the value of the resource. This means that all
-primary key columns must be included in the filter (there are more
-than one when the primary key is compound).
-
If you would like to get the full object back in the response to
your request, include the header `Prefer: return=representation`.
-It will of match exactly the object you sent though.
+Chances are you only want certain information back, though, like
+created ids. You can pass a `select` parameter to affect the shape
+of the response (further documented in the [reading](/api/reading/)
+page). For instance
+
+```HTTP
+POST /people?select=id
+[...]
+```
+returns something like
+```json
+[ { "id": 1 }, { "id": 2 } ]
+```
### Bulk Updates
@@ -110,7 +103,7 @@ Simply use the `DELETE` verb. All recors that match your filter
will be removed. For instance deleting inactive users:
```HTTP
-DELETE /user?active=eq.false
+DELETE /user?active=is.false
```
### Protecting Dangerous Actions
@@ -118,7 +111,6 @@ DELETE /user?active=eq.false
Notice that it is very easy to delete or update many records at
once. In fact forgetting a filter will affect an entire table!
-