Is it possible to build a REST API in a Canister?

I would like to build a backend with REST API is this possible? I only found examples for Web apps. Thanks.

3 Likes

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.

4 Likes

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.

2 Likes

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:

  1. Providing a backend that matches an existing API without replacing clients
  2. An interim solution until more agents are written in languages that clients support
4 Likes

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,
)