In RESTful APIs, typically path parameters (e.g. /some/unique/resource/
) are used to represent resources, and query parameters (e.g. ?sort=asc
) are used to control how these resources are being loaded through e.g. sorting, pagination, filtering, …
As first [discussed in #17631](https://github.com/bitcoin/bitcoin/pull/17631#discussion_r733031180), the current REST api contains two endpoints /headers/
and /blockfilterheaders/
that rather unexpectedly use path parameters to control how many (filter) headers are returned in the response. While this is no critical issue, it is unintuitive and we are still early enough to easily phase this behaviour out and ensure new endpoints (if any) do not have to stick to non-standard behaviour just for internal consistency.
In this PR, a new HTTPRequest::GetQueryParameter
method is introduced to easily parse query parameters, as well as two new /headers/
and /blockfilterheaders/
endpoints that use a count query parameter are introduced. The old path parameter-based endpoints are kept without too much overhead, but the documentation now points to the new query parameter-based endpoints as the default interface to encourage standardness.
Behaviour change
New endpoints and default values
/headers/
and /blockfilterheaders/
now have 2 new endpoints that contain query parameters (?count=<count>
) instead of path parameters (/<count>/
), as described in REST-interface.md. Since query parameters can easily have default values, I have set this at 5 for both endpoints.
headers
GET /rest/headers/<BLOCK-HASH>.<bin|hex|json>?count=<COUNT=5>
should now be used instead of
GET /rest/headers/<COUNT>/<BLOCK-HASH>.<bin|hex|json>
blockfilterheaders
GET /rest/blockfilterheaders/<FILTERTYPE>/<BLOCK-HASH>.<bin|hex|json>?count=<COUNT=5>
should now be used instead of
GET /rest/blockfilterheaders/<FILTERTYPE>/<COUNT>/<BLOCK-HASH>.<bin|hex|json>
Some previously invalid API calls are now valid
API calls that contained query strings in the URI could not be parsed prior to this PR. This PR changes behaviour in that previously invalid calls (e.g. GET /rest/headers/5/somehash.json?someunusedparam=foo
) would now become valid, as the query parameters are properly parsed, and discarded if unused.
For example, prior to this PR, adding an irrelevant someparam
parameter would be illegal:
0GET /rest/headers/5/0000004c6aad0c89c1c060e8e116dcd849e0554935cd78ff9c6a398abeac6eda.json?someparam=true
1->
2Invalid hash: 0000004c6aad0c89c1c060e8e116dcd849e0554935cd78ff9c6a398abeac6eda.json?someparam=true
This behaviour change affects all rest endpoints, not just the 2 new ones introduced here.
(Note: I’d be open to implementing additional logic to refuse requests containing unrecognized query parameters to minimize behaviour change, but for the endpoints that we currently have I don’t really see the point for that added complexity. E.g. I don’t see any scenarios where misspelling a parameter could lead to harmful outcomes)
Using the REST API
To run the API HTTP server, start a bitcoind instance with the -rest
flag enabled. To use the
blockfilterheaders
endpoint, you’ll also need to set -blockfilterindex=1
:
0./bitcoind -signet -rest -blockfilterindex=1
As soon as bitcoind is fully up and running, you should be able to query the API, for example by
using curl on the command line: curl "127.0.0.1:38332/rest/chaininfo.json"
.
To more easily parse the JSON output, you can also use tools like ‘jq’ or json_pp
, e.g.:
0curl -s "localhost:38332/rest/blockfilterheaders/basic/0000004c6aad0c89c1c060e8e116dcd849e0554935cd78ff9c6a398abeac6eda.json?count=2" | json_pp .
To do
- update
doc/release-notes
Feedback
This is my first PR (hooray!). Please don’t hold back on any feedback/comments/nits/… you may have, big or small, whether they are code, process, language, … related. I welcome private messages too if there’s anything you don’t want to clutter the PR with. I’m here to learn and am grateful for everyone’s input.