diff --git a/bigchaindb/web/server.py b/bigchaindb/web/server.py
index 022320d7..91892807 100644
--- a/bigchaindb/web/server.py
+++ b/bigchaindb/web/server.py
@@ -13,6 +13,7 @@ import gunicorn.app.base
from bigchaindb import utils
from bigchaindb import Bigchain
from bigchaindb.web.routes import add_routes
+from bigchaindb.web.strip_content_type_middleware import StripContentTypeMiddleware
# TODO: Figure out if we do we need all this boilerplate.
@@ -60,6 +61,7 @@ def create_app(*, debug=False, threads=1):
"""
app = Flask(__name__)
+ app.wsgi_app = StripContentTypeMiddleware(app.wsgi_app)
CORS(app)
diff --git a/bigchaindb/web/strip_content_type_middleware.py b/bigchaindb/web/strip_content_type_middleware.py
new file mode 100644
index 00000000..953c8b78
--- /dev/null
+++ b/bigchaindb/web/strip_content_type_middleware.py
@@ -0,0 +1,27 @@
+import logging
+
+logger = logging.getLogger(__name__)
+
+
+class StripContentTypeMiddleware:
+ """WSGI middleware to strip Content-Type header for GETs."""
+
+ def __init__(self, app):
+ """Create the new middleware.
+
+ Args:
+ app: a flask application
+ """
+ self.app = app
+
+ def __call__(self, environ, start_response):
+ """Run the middleware and then call the original WSGI application."""
+
+ if environ['REQUEST_METHOD'] == 'GET':
+ try:
+ del environ['CONTENT_TYPE']
+ except KeyError:
+ pass
+ else:
+ logger.debug('Remove header "Content-Type" from GET request')
+ return self.app(environ, start_response)
diff --git a/docs/README.md b/docs/README.md
index 5169f871..220569e2 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,4 +1,5 @@
-[Documentation on ReadTheDocs](http://bigchaindb.readthedocs.org/)
+- [Documentation on ReadTheDocs](http://bigchaindb.readthedocs.org/)
+- [BigchainDB Upgrade Guides](upgrade-guides/)
# The BigchainDB Documentation Strategy
diff --git a/docs/server/source/data-models/inputs-outputs.rst b/docs/server/source/data-models/inputs-outputs.rst
index 76d7062d..696dac83 100644
--- a/docs/server/source/data-models/inputs-outputs.rst
+++ b/docs/server/source/data-models/inputs-outputs.rst
@@ -29,7 +29,7 @@ A CREATE transaction should have exactly one input. That input can contain one o
See the reference on :ref:`inputs ` for more description about the meaning of each field.
To calculate a fulfillment URI, you can use one of the
-:ref:`BigchainDB drivers or transaction-builders `,
+:ref:`BigchainDB drivers or transaction-builders `,
or use a low-level crypto-conditions library as illustrated
in the page about `Handcrafting Transactions `_.
@@ -52,7 +52,7 @@ See the reference on :ref:`outputs ` for more description about the mean
Below is a high-level description of what goes into building a ``condition`` object.
To construct an actual ``condition`` object, you can use one of the
-:ref:`BigchainDB drivers or transaction-builders `,
+:ref:`BigchainDB drivers or transaction-builders `,
or use a low-level crypto-conditions library as illustrated
in the page about `Handcrafting Transactions `_.
diff --git a/docs/server/source/drivers-clients/index.rst b/docs/server/source/drivers-clients/index.rst
index f6e5c6ae..2c4f3f01 100644
--- a/docs/server/source/drivers-clients/index.rst
+++ b/docs/server/source/drivers-clients/index.rst
@@ -1,5 +1,5 @@
-Drivers & Clients
-=================
+Drivers & Tools
+===============
Libraries and Tools Maintained by the BigchainDB Team
-----------------------------------------------------
diff --git a/docs/upgrade-guides/v0.10-v1.0.md b/docs/upgrade-guides/v0.10-v1.0.md
new file mode 100644
index 00000000..63778371
--- /dev/null
+++ b/docs/upgrade-guides/v0.10-v1.0.md
@@ -0,0 +1,433 @@
+# Updating from BigchainDB v0.10 to v1.0
+
+BigchainDB v1.0 stands for backwards compatibility. This means that all
+following [minor](http://semver.org/) releases after version 1.0 will always be
+backwards-compatible to previous versions.
+
+For all future releases, we commit to not introduce breaking changes to the
+public interfaces of BigchainDB's:
+
+- [Data
+ model](https://docs.bigchaindb.com/projects/server/en/latest/data-models/index.html)
+- [HTTP
+ API](https://docs.bigchaindb.com/projects/server/en/latest/http-client-server-api.html)
+- [WebSocket Event Stream
+ API](https://docs.bigchaindb.com/projects/server/en/latest/websocket-event-stream-api.html)
+
+
+As we saw the version bump to v1.0 as our last chance in a while to fix minor
+annoyances, we intentionally did clean up on the above interfaces. In this
+document, we'd like to give a comprehensive summary of those changes to allow
+you to upgrade efficiently.
+
+The next sections will go over each of the above mentioned interfaces and
+detail the exact changes.
+
+## A note upfront
+
+We tried to test this upgrade guide as best as we could by using it to adjust
+our official drivers. If you still find breaking changes that causes your
+software to crash, please let us and others reading this guide know by sending
+over a Pull-Request or notifying us on Gitter.
+
+Thank you very much :)
+
+
+## Syntactical changes
+
+#### `tx`, `txid` and `tx_id` becomes `transaction_id`
+
+To establish better consistency between external interfaces, all usages of
+`txid`, `tx` and `tx_id` in data models and HTTP API were renamed to
+`transaction_id` or `transaction`.
+
+
+## Breaking Changes to the Data Model
+
+#### Output amount is now a string
+
+BigchainDB transactions may have multiple inputs and outputs, and each output
+has an amount, which is the integral number of the asset being transferred. In
+prior versions of BigchainDB, the amount was encoded as a number, which on the
+face of it is the obvious way to encode an integer. However, as usual the devil
+is in the details; JSON, the encoding of choice for BigchainDB transactions,
+encodes all numbers including integers as floating point. This isn't a problem
+for the majority of circumstances where numbers are small, however in some
+environments and for some use cases\*, the number may lose precision.
+
+In order to safeguard against this, amounts are now encoded as strings, and it
+is recommended to use a decimal math library (such as
+[big.js](https://github.com/MikeMcl/big.js)) when dealing with large numbers in
+Javascript. Additionally, numbers are capped at 9e18 to stay comfortably within
+the boundary of a 64 bit signed integer.
+
+\* Try this in the Chrome developer console: `2**60 == 2**60+1`.
+
+
+#### Input `fulfills.txid` is now `transaction_id`
+
+We renamed a TRANSFER transaction's `inputs.fulfills.txid` to
+`inputs.fulfills.transaction_id`.
+
+#### Input `fulfills.output` is now `output_index`
+
+We renamed a TRANSFER transaction's `inputs.fulfills.output` to
+`inputs.fulfills.output_index`.
+
+#### Signing payload is now the transaction body
+
+The signature payload of a BigchainDB transaction is now "just" the JSON
+serialized body of the transaction. This change is invisible to applications
+that do not produce transactions with more than one input. However, prior to
+the 1.0 release, transactions with multiple inputs had a special signing
+protocol, which included reassembly of the transaction. This was identified as
+being unneeded, so now the payload that is signed is always just the serialized
+transaction, minus signatures. More details, take a look at the
+[Pull-Request](https://github.com/bigchaindb/bigchaindb/pull/1225) introducing
+the change or at our updated [Handcrafting
+Transactions](https://docs.bigchaindb.com/projects/py-driver/en/latest/handcraft.html)
+document.
+
+
+#### Update to Crypto-Conditions version 2
+
+Earlier this year the IETF Interledger working group released an [updated
+draft](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02) of their
+Crypto-Conditions specification. To send transactions to BigchainDB v1.0, all
+transaction's inputs and outputs need to comply to this new version.
+
+Several of the language specific implementations have already been updated,
+including:
+
+- [py-crypto-conditions](https://github.com/bigchaindb/cryptoconditions)
+- [js-crypto-conditions](https://github.com/interledgerjs/five-bells-condition)
+- [java-crypto-conditions](https://github.com/interledger/java-crypto-conditions)
+
+
+If you don't find your preferred language in this list, do not despair but
+reach out to us for help on Github/Gitter or product@bigchaindb.com.
+
+
+#### Revamp of Crypto-Conditions signing details
+
+In order to create a correct fulfillment for an output condition in BigchainDB,
+we include the conditon URI ("ni:///sha-256;..."), to verify the fulfillment
+against. However, the condition URI does not tell you who may sign in order to
+create a correct fulfillment.
+
+For this, we have the `condition.details` object. This is a recursive data structure
+which mirrors the n-of-m threshold / ed25519 condition types that we support.
+
+An example of the new structure is:
+
+```json
+{
+ "details": {
+ "type": "threshold-sha-256",
+ "threshold": 2,
+ "subconditions": [
+ {
+ "public_key": "",
+ "type": "ed25519-sha-256",
+ },
+ {
+ "public_key": "",
+ "type": "ed25519-sha-256",
+ }
+ ],
+ },
+}
+```
+
+#### Transaction version is now 1.0
+
+The `version` key in the transaction is now set to `'1.0'`.
+
+
+## Breaking Changes to the HTTP API
+
+In this section, we'll go over each of the endpoints separately and list the
+changes done to them:
+
+
+### `GET /`
+
+Documentation:
+
+- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#bigchaindb-root-url)
+- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#bigchaindb-root-url)
+
+
+Changes:
+
+- All notion of `_links` was removed
+- `api_v1` is now an object including currently only one further object called
+ `v1`
+- `api.v1` includes links that were originally only available through
+ `/api/v1/`
+- `api.v1` now also includes links to `assets` (a new endpoint) and `outputs`
+- `streams_v1`'s link was changed from `streams/valid_tx` to
+ `streams/valid_transactions`
+- `streams_v1` was renamed to `streams`
+- Usages of scheme, host and port to API V1's endpoints were removed to allow
+ for configurations of BigchainDB behind reverse proxies
+ - e.g. `http://example.com:9984/api/v1/transactions` ==>
+ `/api/v1/transactions`
+
+
+```json
+// Old
+{
+ "_links": {
+ "api_v1": "http://example.com:9984/api/v1/",
+ "docs": "https://docs.bigchaindb.com/projects/server/en/v0.10.2/"
+ },
+ "keyring": [
+ "6qHyZew94NMmUTYyHnkZsB8cxJYuRNEiEpXHe1ih9QX3",
+ "AdDuyrTyjrDt935YnFu4VBCVDhHtY2Y6rcy7x2TFeiRi"
+ ],
+ "public_key": "NC8c8rYcAhyKVpx1PCV65CBmyq4YUbLysy3Rqrg8L8mz",
+ "software": "BigchainDB",
+ "version": "0.10.2"
+}
+
+// New
+{
+ "api": {
+ "v1": {
+ "docs": "https://docs.bigchaindb.com/projects/server/en/v0.11.0.dev/http-client-server-api.html",
+ "statuses": "/api/v1/statuses/",
+ "streams": "ws://example.com:9985/api/v1/streams/valid_transactions",
+ "transactions": "/api/v1/transactions/",
+ "assets": "/api/v1/assets/",
+ "outputs": "/api/v1/outputs/"
+ }
+ },
+ "docs": "https://docs.bigchaindb.com/projects/server/en/v0.11.0.dev/",
+ "keyring": [
+ "6qHyZew94NMmUTYyHnkZsB8cxJYuRNEiEpXHe1ih9QX3",
+ "AdDuyrTyjrDt935YnFu4VBCVDhHtY2Y6rcy7x2TFeiRi"
+ ],
+ "public_key": "NC8c8rYcAhyKVpx1PCV65CBmyq4YUbLysy3Rqrg8L8mz",
+ "software": "BigchainDB",
+ "version": "0.11.0.dev"
+}
+```
+
+### `GET /api/v1`
+
+Documentation:
+
+- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#api-root-endpoint)
+- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#api-root-endpoint)
+
+Changes:
+
+- All notion of `_links` was removed
+- The response object of `/api/v1` now includes links to `assets` (a new
+ endpoint) and `outputs`
+- `streams_v1`'s link was changed from `streams/valid_tx` to
+ `streams/valid_transactions`
+- `streams_v1` was renamed to `streams`
+- Usages of scheme, host and port to API V1's endpoints were removed to allow
+ for configurations of BigchainDB behind reverse proxies
+ - e.g. `http://example.com:9984/api/v1/transactions` ==>
+ `/api/v1/transactions`
+
+
+```json
+// Old
+{
+ "_links": {
+ "docs": "https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html",
+ "self": "http://example.com:9984/api/v1/",
+ "statuses": "http://example.com:9984/api/v1/statuses/",
+ "streams_v1": "ws://example.com:9985/api/v1/streams/valid_tx",
+ "transactions": "http://example.com:9984/api/v1/transactions/"
+ }
+}
+
+// New
+{
+ "docs": "https://docs.bigchaindb.com/projects/server/en/v0.11.0.dev/http-client-server-api.html",
+ "statuses": "/api/v1/statuses/",
+ "streams": "ws://example.com:9985/api/v1/streams/valid_transactions",
+ "transactions": "/api/v1/transactions/",
+ "assets": "/api/v1/assets/",
+ "outputs": "/api/v1/outputs/"
+}
+```
+
+
+### `GET /api/v1/transactions/{tx_id}`
+
+Documentation:
+
+- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#get--api-v1-transactions-tx_id)
+- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#get--api-v1-transactions-transaction_id)
+
+
+Changes:
+
+- Previously this endpoint returned transactions from BigchainDB's `BACKLOG`
+and from blocks marked as `UNDECIDED`. With version 1.0, this endpoint will
+only return transactions included in blocks marked as `VALID`.
+
+
+### `POST /api/v1/transactions`
+
+Documentation:
+
+- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#post--api-v1-transactions)
+- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#post--api-v1-transactions)
+
+
+Changes:
+
+- A `Location` HTTP header was included in the endpoint's response to allow
+ users to check the transaction's status more easily via the
+ `/statuses?transaction_id` endpoint
+
+
+### `GET /api/v1/outputs`
+
+Documentation:
+
+- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#get--api-v1-outputs?public_key=public_key)
+- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#get--api-v1-outputs?public_key=public_key)
+
+
+Changes:
+
+- Reversed the behavior of the `unspent` query parameter to `spent`, implying
+ the following behavior:
+ - If `?spent=true`, the response is an array of all spent outputs
+ associated with a given public key
+ - If `?spent=false`, response is an array of all NOT YET spent (or
+ "unspent" outputs associated with a given public key
+ - If no ``spent=` filter is present in the request, the response is an
+ array of all outputs associated with a given public key (spent and
+ unspent)
+
+Previously the response included a list of relative URLs pointed to
+transations' outputs:
+
+```json
+// Old
+[
+ "../transactions/2d431073e1477f3073a4693ac7ff9be5634751de1b8abaa1f4e19548ef0b4b0e/outputs/0"
+]
+
+// New
+[
+ {
+ "output_index": 0,
+ "transaction_id": "2d431073e1477f3073a4693ac7ff9be5634751de1b8abaa1f4e19548ef0b4b0e"
+ }
+]
+```
+
+In the future, we're planning to [upgrade this endpoint
+further](https://github.com/bigchaindb/bigchaindb/blob/99499b1f8783719a082813912ac9a0d363ae278f/bdb-ip.md#6-a-new-outputs-endpoint)
+to meet the requirements of [our
+users](https://github.com/bigchaindb/bigchaindb/issues/1227#issuecomment-307297473).
+
+
+### `GET /api/v1/statuses?tx_id`
+
+Documentation:
+
+- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#get--api-v1-statuses?tx_id=tx_id)
+- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#get--api-v1-statuses?transaction_id=transaction_id)
+
+
+Changes:
+
+- All notion of `_links` was removed. In case of querying the status of a
+ transaction already included in a block marked `VALID`, no `_links` object is
+ provided anymore. The response object now only contains a single key value
+ pair named `status`
+- The query parameter `tx_id` was renamed to `transaction_id`, e.g. `GET
+ /api/v1/statuses?transaction_id=`
+
+
+```json
+// Old
+{
+ "status": "valid",
+ "_links": {
+ "tx": "/transactions/04c00267af82c161b4bf2ad4a47d1ddbfeb47eef1a14b8d51f37d6ee00ea5cdd"
+ }
+}
+
+// New
+{
+ "status": "valid",
+}
+```
+
+
+### `GET /api/v1/statuses?block_id`
+
+Documentation:
+
+- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#get--api-v1-statuses?block_id=block_id)
+- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#get--api-v1-statuses?block_id=block_id)
+
+
+Changes:
+
+- All notion of `_links` was removed. The response object now only contains a
+ single key value pair named `status`
+
+
+```json
+// Old
+{
+ "status": "valid",
+ "_links": {
+ "tx": "/transactions/04c00267af82c161b4bf2ad4a47d1ddbfeb47eef1a14b8d51f37d6ee00ea5cdd"
+ }
+}
+
+// New
+{
+ "status": "valid",
+}
+```
+
+
+### `GET /api/v1/blocks?tx_id`
+
+Documentation:
+
+- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#get--api-v1-blocks?tx_id=tx_id&status=UNDECIDED|VALID|INVALID)
+- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#get--api-v1-blocks?transaction_id=transaction_id&status=UNDECIDED|VALID|INVALID)
+
+
+Changes:
+
+- The query parameter `tx_id` was renamed to `transaction_id`, e.g. `GET
+ /api/v1/blocks?transaction_id`
+
+
+## Breaking Changes to the WebSocket Event Stream API
+
+In the event object sent to a listener, `tx_id` was renamed to
+`transaction_id`.
+
+```json
+// Old
+{
+ "tx_id": "",
+ "asset_id": "",
+ "block_id": ""
+}
+
+// New
+{
+ "transaction_id": "",
+ "asset_id": "",
+ "block_id": ""
+}
+```
diff --git a/tests/web/test_content_type_middleware.py b/tests/web/test_content_type_middleware.py
new file mode 100644
index 00000000..103bd615
--- /dev/null
+++ b/tests/web/test_content_type_middleware.py
@@ -0,0 +1,40 @@
+from unittest.mock import Mock
+
+OUTPUTS_ENDPOINT = '/api/v1/outputs/'
+
+
+def test_middleware_does_nothing_when_no_content_type_is_provided():
+ from bigchaindb.web.strip_content_type_middleware import StripContentTypeMiddleware
+ mock = Mock()
+ middleware = StripContentTypeMiddleware(mock)
+ middleware({'REQUEST_METHOD': 'GET'}, None)
+
+ assert 'CONTENT_TYPE' not in mock.call_args[0][0]
+
+
+def test_middleware_strips_content_type_from_gets():
+ from bigchaindb.web.strip_content_type_middleware import StripContentTypeMiddleware
+ mock = Mock()
+ middleware = StripContentTypeMiddleware(mock)
+ middleware({'REQUEST_METHOD': 'GET',
+ 'CONTENT_TYPE': 'application/json'},
+ None)
+
+ assert 'CONTENT_TYPE' not in mock.call_args[0][0]
+
+
+def test_middleware_does_notstrip_content_type_from_other_methods():
+ from bigchaindb.web.strip_content_type_middleware import StripContentTypeMiddleware
+ mock = Mock()
+ middleware = StripContentTypeMiddleware(mock)
+ middleware({'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'application/json'},
+ None)
+
+ assert 'CONTENT_TYPE' in mock.call_args[0][0]
+
+
+def test_get_outputs_endpoint_with_content_type(client, user_pk):
+ res = client.get(OUTPUTS_ENDPOINT + '?public_key={}'.format(user_pk),
+ headers=[('Content-Type', 'application/json')])
+ assert res.status_code == 200