Question on http_request()

Looking at Introducing a new approach to handling HTTP requests and serving assets :: Internet Computer

Can Motoko canisters implement the http_request() method?

1 Like

Yes you definitely can! That’s actually what our asset canister is doing - it’s just a Motoko canister implementing http_request that we include with the SDK.

I’m hoping we can create a Vessel package to make it really easy to add asset functionality to canisters and also open source our SDK codebase soon so I can start linking to relevant code

1 Like

I find it a bit confusing how this all used to work, could you help me please?

  1. Accessing the canister through <CANISTER_ID>.ic0.app calls the asset canisters retrieve() function without arguments
  2. This returns a blob which consists of a index.js file that contains some JS and static HTML → the so called bootstrap code
  3. Executing this bootstrap code then did the following things
    3.1 create worker
    3.2 polyfill window.ic
    3.3 call retrieve again, but this time with index.js as an argument
    3.4 pass control of the DOM and the page to the newly fetched index.js from 3.3

Is this correct?

1 Like

Oh and is this the middleware server?

https://docs.rs/tiny_http/0.8.1/tiny_http/

Isn’t the middleware server a single point of failure and centralization?

I don’t think we have retrieve() anymore, nor the bootstrap code. Are you looking at old versions of the asset canister?

Yes, I’m reading the article @Hazel linked where the workings of the old assets canister are explained

@kpeacock - Do you have any examples you could share :sweat_smile: ?

Or, is it as-simple-as just implementing the interfaces here in Motoko
(and setting the type to asset?)

and doing something like…

public shared func http_request(req : HttpRequest) : async HttpResponse {
  // Do stuff w/ req, build response
};

Make sure you mark it as a query method, but yes, it is as simple as that. Try this as an (untested) starting point:

shared actor {

  type HeaderField = (Text, Text);

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

  type HttpResponse = {
    status_code: Nat16;
    headers: [HeaderField];
    body: Blob;
  };

  public query func http_request(request: T.HttpRequest): async T.HttpResponse {
    …
  }
}

(I left out the streaming part, for simple experiments this should not be needed. Thanks to Candid subtyping, it should work fine.)

Note that Motoko’s support for string parsing, e.g. for headers, is limited. Community-provided libraries are welcome!

4 Likes

Will give this a shot after work today. I’m super excited for this, great job everyone!!!

2 Likes

Hi @Hazel

Any luck with this?

I’m also interested but if you got this working there’s no point for me to reinvent the wheel.

Can you share your code please?

1 Like

Working example!

2 Likes