I am attempting to create a REST API using rust ICP http canister as the server. I was able to get this 2024 demo working:
However I noticed the certification steps may be over-simplified and am seeking clarification. The demo repo is written as:
GET /todos => return array of todo items
POST /todos => create todo item
As a brief recap, recall that “certification” proves a response has not been tampered with by icp canister nodes. In order to certify, it needs to add a proof to a certification tree. This requires you to know the response shape ahead of time.
The demo repo accomplishes this by re-generating the cert for GET/todos at the end of the POST/todos operation. The newly created todo item is now included in the certification proof for GET/todos. However this assumes the GET/todos operation has no query params that might change the shape of the result. The demo repo GET/todos always returns the same “hardcoded” array of todo items. This does not reflect real world use-cases where response bodies are dynamic.
My questions are:
(1) How can developers certify dynamic response bodies in anticipation of unknown user query params? Can it be done without bloating the cert tree? Is the solution to make it an icp update?
(2) If I wanted to change GET/todos into POST/todos/list with body containing config object, would i still be able to register it as an icp query or must i turn it into an icp update and go through expensive slow consensus?
(3) Is there any other example repos or community projects that have solved this and can be used as a reference? (so far the only recent one i found was the github link listed above)
Tagging a few folks in hopes they see & maybe this thread helps future developers. @NathanosDev@Kepler
Myself from OfficeX team, and 2 other stealth ICP teams are dealing with this same question. Solving this would be a huge unblocker for 3 ecosystem projects
I am currently working on it on this OfficeX canisters-official repo (in case any other developers need a reference, after we get this working).
Serving HTTP Requests Dynamically
This wiki article describes how a canister can a-priori create certificates for assets and then serve these assets to the user. What if a canister has to dynamically generate a HTTP response based on the input of http_request method? In this case, the HTTP response doesn’t include a certificate and cannot be trusted. To improve the trust in this case, a HTTP response includes an upgrade tag. If this tag is set, then the HTTP gateway processing the HTTP response would send the request again to an “update” method called http_request_update. The http_request_update method is a built-in method that also serves HTTP requests. As the responses to update calls are certified by the Internet Computer, this mechanism can be used to serve HTTP requests dynamically in a trustworthy way.
It sounds like the solution here is to force all dynamic REST responses to be an icp update instead of icp query. The update will force it to go through consensus and that acts as proof rather than the certification tree which wont get involved?
For simplicity, would it be okay to just make every REST interaction go through icp update? Would this allow me to not worry about certification altogether? (is this a bad idea or a good tradeoff?)
It sounds like the solution here is to force all dynamic REST responses to be an icp update instead of icp query.
This is the correct answer👆
There is a way to force the boundary node to call back from http_request with a call to http_request_update(from memory). This will let you certify and then return a redirect header that will request. Crappy for latency, but should work. Of course once you have the item in verification, the next time it is called you can just return the query with the cert.
And yes…it would be impossible to hold all possible combinations of a bunch of random variables that are all use configurable, so you’ll need some way to cull the bloat.
Alternatively you can use the raw api and self certify with something in your header…this will be less secure, but may work for some applications (but then again you can just use raw.)
Thanks so much @skilesare ! That gives reassurance and we will proceed to use ic-update for all REST API calls, then potentially figure out optimizations later. Much appreciated