Enable canisters to make HTTP(S) requests

You are very much welcome!

And I am also eagerly waiting for it

2 Likes

Indeed! Just to add another dimension to what Diego was saying: What you could do for now, however, is to build an outside service that periodically queries your canister for API calls that should be made, if a call is available, you fetch it with an update call, then make the API call with the outside service, and return it to the canister with an update call. That would be similar to how an oracle would work to connect to the outside world and would allow you to make API calls already now before this feature is available, but with less decentralization (and coolness). You can probably put an oracle like this together quickly and get going already now with your ideas. Later you can switch over to this feature.

4 Likes

What is this in the documentation for management canister? It says it has http_request in the docs, when it was recently updated a few days ago. https://smartcontracts.org/docs/current/references/ic-interface-spec/#icmethod-http_request . Is this supposed to just be a preview and not actually available?

And also, it seems like the ledger has an http request, (albeit the one that is used to deploy the icp ledger itself, and not the interface you use to interact with the icp leger) has an inbuilt http request. interfaces/nns/ledger.did | ic.rocks
Is this somehow like an early version thats already enabled?

http_request handles incoming requests.

Oh wait why is there a url field in it? Otherwise if it was to take http request to itself, the url would be the canister ledger/management canister itself no? And you wouldnt need to specify then.

See this: it is there for parsing the url: ICDevs.org Bounty #8 - HttpRequest Parser

Oh that makes sense. Thanks

Yes, I intended that will do like that.
Many thanks

I have tried using the API, but I received this error running it locally:

Call was rejected:
Request ID: 642a845ac4a960ad87233acb8f75fad6daecb1193ec1b3a694a97561f10ca0ea
Reject code:
Reject text: This API is not enabled on this subnet

Can I enable it?

Can you show your code? This may be related to the new dfx 10, but that seems very odd.

Thanks for the reply, just a small snippet to test the function:

import Nat "mo:base/Nat";
import Text "mo:base/Text";
import Debug "mo:base/Debug";


actor {

type HttpHeader = { name: Text; value: Text };

type HttpResponse =  {
  status: Nat;
  headers: [HttpHeader];
  body: Blob;
};

type HeaderField = (Text, Text);

type HttpRequest = {
  url : Text;
  method : { #get };
  headers : [HeaderField];
  body : Blob;
  };

 let IC = actor "aaaaa-aa" : actor {
 http_request : (HttpRequest) -> async (HttpResponse);
 };

  public func req(url:Text) : async () {
    Debug.print("URL: " # url);
      var myReq : HttpRequest = {
      url= url;
      method = #get;
      headers= [  ("content-type", "text/plain") ];
      body = Text.encodeUtf8("Counter");
    };

    var res = await IC.http_request(myReq);
    Debug.print("Response Code " # Nat.toText(res.status));
  };

};

You are asking the ic root canister for its http_request function. I don’t think it has one.

Let is not how you use that API. Typically you don’t call that from other canister. You can implement that function so web browser can call and ask for information from your canister, but it is not an outgoing httprequest.

I thougth it could be used to do outgoing HTTP request when I read the doc: The Internet Computer Interface Specification | Internet Computer Developer Portal , but maybe it can be done from one canister to another, I guess…

I succesfully received http requests from www to my canister, but I need to make a request from my canister to web2 to create integration with payment methods ( Like stripe) for exemple.

That is “coming soon” but I think will only be one shot get requests. I don’t think your canister will be able to process the response. There was some talk of trying to get this to work, but it seems like a vile sin against determinism. :man_shrugging: Plus, who is going to put their stripe key on 8 servers they don’t own? My guess is, best case in the medium term is you can ping a service that does some work and pushes the data you need on to the IC. You can do the same right now by polling.

1 Like

How can we do anything with the data returned if it’s one-shot? I sincerely hope the request enables us to use the data. What the IC really needs is a time-out.

It has always seemed like outgoing requests would break determinism for me. You can trust one node to execute the task and trust them, but that is a recipe for disaster. Having n number call the same web 2 post will never provide sufficient responses to reach consensus. Imagine 8 servers all hitting the same submit_payment stripe api at the same time. A bunch are going to get duplicate request errors and if the stripe programmers are really good only one will submit the payment. How does a dev tell the IC to deal with that mess? Even a time stamp in a get request requires dev intervention. Poll and push by a trusted party is going to be massively less complex.

I think the IC has a clever solution to the consensus problem, the idea being devs would write reducers and so when a requests goes through the consensus, we would not get the whole response but only on some function of it, which could exclude the timestamps and just query for the relevant information. I think info is fine, more complex stuff with payments I have no idea how the IC will solve.

I guess they will be get requests, but not on-shot. Update may not work for the IC.

I’ve seen some stuff about the reducers, but I can’t imagine they will be worth the trouble for anything but simple data feed requests. I can’t imagine writing a decentralized service with any kind of decent value associated with it and trust an external http request. You are at the complete mercy of the service provider not faking data. Maybe if it is your own service, but again, Poll and push just seems so much easier of a pattern.

How is Chainlink solving this?

1 Like