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?

4 Likes

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!

6 Likes

If I might humbly suggest…This is code that should be presented widely so folks can visualize.

‘’ Whoa, it works!! ‘’

Very flash Hazel.

This looks great for hard coded or programmatic responses, but how do you read in your source files…like have some HTML that I want to return for a certain path…how can motoko load in that file and serve it up?

I think the asset canister that gets created by dfx should allow you to do that.

Has anyone gotten html templating to work with rust, or is building something for motoko?

Is DFX open sourced? It looks like the asset canisters just have a putAsset, getAsset, and http_request() that serve the named assets. Seems like this would be an easy set of motoko function to just lift and put into your core canister rather than having a separate canister.

Good question, I wonder myself whether DFX is open-sourced…

Dfx is not (yet?) open source, but the asset canister is since a few days: GitHub - dfinity/certified-assets: A certified assets canister written in Rust.