Feature request: map appropriate HTTP request methods to update calls

I brought this up here but that thread has gotten long and there are multiple conversations happening:

I would like to request that appropriate HTTP request methods are mapped to update calls instead of query.

I think at least POST, PUT, PATCH, and DELETE would be a great start.

I could make a PR to agent-rs to do this but it would need the equivalent support in replicas.

2 Likes

Actually, the HTTP handling is done by the icx-proxy component in the agent-rs repo, which already is open source, so a feature request there is not inappropriate.

Turning POST into an update call is certainly a possibility. I think we have hesitated because maybe not every POST should be an update call? Imagine an image transcoding service – you probably upload the file with POST, but maybe still want the performance of a query call. Also, despite best intentions in the HTTP spec, in practice you might want state modification on GET as well in some cases.

So tying it to the method seems a bit too rigid.

In my prototype, a query call is done first, and but it can tell the proxy to upgrade to an update call, but it’s also not clear if that’s ideal.

If you don’t mind having an URL that is not *.ic0.app, at least for experimentation, you can run a patched icx-proxy on your own infrastructure, and use that. The HTTP handling sits nicely on top of the core IC, instead of being a feature you can’t extract.

4 Likes

This is great news. Since I’m going to do this anyway I’ll probably make a PR and then it can be debated there :grinning_face_with_smiling_eyes:

In one of my use cases I could possibly run a forked version but it would be a lot neater not to.

My plan was to make the mapping configurable but with some defaults that match the intentions of the HTTP spec.

That way, different instances of the proxy could be configured differently on start up. It could even be as granular as mapping a specific route to a certain call rather than the entire request method.

Could you help me understand how that would work? I thought an update call is the only way to modify state.

1 Like

That’s what I mean with a image transcoding: You POST a .gif, it returns a .jpg, but doesn’t actually store anything. Not saying it’s a great example for an on-IC-app, but maybe still can serve as an example for a POST call that you want to get query-called.

I forked agent-rs and ran it locally, with the change I proposed at the top of this thread.

I encountered 2 problems:

  1. Without a query annotation on http_request, I get Replica Error (3): "IC0302: Canister rrkah-fqaaa-aaaaa-aaaaq-cai has no query method 'http_request'"

  2. When making an update call via http_request I get 500 Internal Server Error on the client and see WARN Internal Error during request: CertificateVerificationFailed on the server.

It looks like #1 would require a change to the replica code to allow http_request to have a shared annotation.

I haven’t been able to figure out #2 yet.

Re #1: I suggest that your fork uses a different method name (http_update_request). It can have the same implementation, but the system (rightfully) rejects query calls to methods that aren’t marked query.

The replica is not involved here, this is a higher level feature (e.g. you can tell that The Internet Computer Interface Specification :: Internet Computer doesn’t mention it).

Re #2: You probably have to call fetch_root_key in the right spot.

1 Like
4 Likes

My first PR was closed because icx-proxy moved to its own repo.

The most relevant PR now is:

1 Like

The above PR was merged today :slight_smile:

4 Likes

Hallelujah! It is merged! Yay!

1 Like

I’m trying to better understand what this PR does. Will this allow me to send POST/PUT method calls to the IC via HTTP and have them converted into update calls that go to http_request_update? Or is that still a ways off?

Am I correct in saying that http_request only supports GET requests at the moment? Or it handles everything, but if you try to update something it will fail because http_request interface endpoint is a query?

1 Like

Canisters can handle HTTP requests by providing a http_request function. However, http_request only allows making query calls.

With my PR, canisters can now also provide a function called http_request_update that allows making update calls.

When handling a HTTP request inside of http_request, if it’s necessary to make an update call, http_request can now return a response including the field upgrade with a value of true. This results in http_request_update to be called instead.

Whether any of this happens due to HTTP methods like GET or POST (or other aspects of the request) is left entirely up to the canister. I had originally inferred whether to “upgrade” from query call to update based on the HTTP method but allowing the canister to determine that explicitly is more flexible.

7 Likes

Is this live already? If not, what is the ETA? I’m eager to migrate my telegram bot to this interface and disable my own AWS-Bounday-Node (which had this feature for a year now… ;-))

1 Like

@Daniel-Bloom might know.

1 Like

@diegop do you know anything?

1 Like

No, I’ll ask around.

2 Likes

I am fairly certain this hasn’t been rolled out. I checked the update logs and I know for sure about an unrelated issue blocking production upgrades.

I will pull the built binary to ic stop gap repo. & update this thread when prod is up. (This week)

4 Likes

I use this code(feat: upgrade HTTP request calls from query to update upon canister's request by paulyoung · Pull Request #195 · dfinity/agent-rs · GitHub ) and icx-proxy (GitHub - dfinity/icx-proxy: A rust-based command line tool to serve as a gateway for a Internet Computer replica.) to test at local environment.
i try $curl -v -X POST -H “Content-type: application/json” -H “Accept: application/json” -d ‘{}’ ‘http://localhost:8000?canisterId=ai7t5-aibaq-aaaaa-aaaaa-c

But it return : Response to POST request (query)

would you tell where i get worng

That code at the top of the PR is out of date.

Basically, if http_request returns upgrade: true then http_request_update is called.

2 Likes

i just wanna know why your code can return Response to POST request ( update)
but i use you code at my computer return Response to POST request (query)