I would like to build a backend with REST API is this possible? I only found examples for Web apps. Thanks.
Yes. You can implement http_request
in your canister and service requests that way.
Currently only query
calls that don’t mutate state are natively supported (not update
).
I made a pull request to change that but was asked to wait for a proper proposal process to be in place.
See https://forum.dfinity.org/t/feature-request-map-appropriate-http-request-methods-to-update-calls for details.
Worth noting that in the meantime you could run my fork of icx-proxy
somewhere, use @nomeata’s HTTP-to-IC bridge, or your own solution.
Hopefully something supporting update
calls will land and remove the need for all that.
Also worth nothing that I think I prefer @nomeata’s approach of allowing the canister to request that the proxy “upgrade” the call from query
to
update
.
“upgrade” means to make the call again as an update
call, so in general it has the potential to always make 2 calls instead of 1, but it makes no assumptions about how HTTP methods map to the IC.
The compelling examples against my approach from the linked discussion include the need to use HTTP POST but not update state, e.g. an image transcoding service.
In that case my approach is inefficient because it makes an update
call when a query
would do.
The real problem with my approach is that if you need to support an existing API client which makes something like a GET request but then the canister needs to make a state modification. @nomeata’s approach handles that just fine, although there the inefficiency is in making 2 calls.
Thanks for providing the options.
What’s the advantage of building out a separate REST API versus just using the existing Candid RPC platform?
I can think of these:
- Providing a backend that matches an existing API without replacing clients
- An interim solution until more agents are written in languages that clients support
Can we use http_request
(only query
calls) local environment (dfx start --clean
) or we need something more to be configured?
You can use http_request
in a local dfx environment, but I don’t think it will work with vanilla dfx start
.
You’ll need to run dfx replica
in one terminal and icx-proxy
in another. icx-proxy
will need to have the flags that point to the replica and map a DNS name to a canister ID. There’s another thread somewhere in this forum that describes this process in more detail.
Technically, dfx start
runs both dfx replica
and icx-proxy
as of a recent 0.8.x version, but the problem is that it doesn’t configure icx-proxy
with the correct flags to let you call http_request
like you want.
There’s some more detailed info here:
Hi, I have a question what do you mean about " icx-proxy
will need to have the flags that point to the replica"? Is it “–replica” point to such that 127.0.0.1:8000 or other thing?
I run “icx-proxy --dns-alias 127.0.0.1:ajy76-hiaaa-aaaah-aa3mq-cai -v -v --debug --address 127.0.0.1:8000 --replica http://127.0.0.1:8000” in one termimal and dfx replica in another terminal “dfx replica --port 8000”
Then I run “dfx deploy” in my project dir, errors comes out:
May 05 09:21:55.630 WARN Internal Error during request:
hyper::Error(
IncompleteMessage,
)