Can we somehow achieve or build a canister with a interface bahaving like a classic web server

We’re facing huge struggle with the fact, that we cannot easily retrieve multiple assets for the web frontend. What we need is a canister, which is able to resolve arbitrary files by calling https://<canister_id>.ic0.app/path/to/asset.js or something comparable. Are there any plans or ideas on this topic?

I would consider this a fundamental requirement to build full fledged state of the art user interfaces on the IC within reasonable time frames. It looks like it’s only doable by bundling everything into one .js file.

I do not fully understand how the resolver currently works. In my understanding, the request to a specific canister should resolve somehow to its main function? Maybe someone can elaborate on this?

I actually don’t know the state of it, maybe we are not allowed to use it for now, but.

js-user-library/http_agent.js contains the next function (warning! I only have 0.5.5 installed locally, maybe it was changed):

retrieveAsset(canisterId, path) {
    const arg = IDL.encode([IDL.Text], [path]);
    return this.query(canisterId, { methodName: '__dfx_asset_path', arg }).then(response => {
        switch (response.status) {
            case "rejected" /* Rejected */:
                throw new Error(`An error happened while retrieving asset "${path}":\n` +
                    `  Status: ${response.status}\n` +
                    `  Message: ${response.reject_message}\n`);
            case "replied" /* Replied */:
                const [content] = IDL.decode([IDL.Text], response.reply.arg);
                return base64_js_1.toByteArray('' + content);
        }
    });
}

Which could be accessed by a user via <ActorObj>.__getAsset(path).

I never used it (maybe it doesn’t work), but at least it seems like the team is acknowledged about this requirement.

2 Likes

This also means that you should be able to do this from any client (even from CLI) - just call the __dfx_asset_path of your canister.

2 Likes

Oh. It looks like in 0.6.7 you need to create a separate canister for this.
At least dfx new's default hello-world canister does this. You should check it out.

Thanks! Yes I’m on the latest version. But the same holds true. There is no easy way to request particular assets without resolving them via JavaScript by utilizing the canister API.

You can retrieve files by importing the asset canister.

import asset from 'ic:canister/your_asset_canister';
const content = await asset.retrieve('file to retrieve');
const string = new TextDecoder().decode(new Uint8Array(content));
1 Like

Yes, I’m aware of this. But this is not a solution in my eye. A modern web application will load the assets via sub/path/to/asset/whatever.file. Service worker for example cannot be register the proposed way. They need to be loaded via https.

2 Likes

I agree these are major problems. I’ve reached out to the team separately, hopefully we can get these capabilities added.

I don’t see why the static asset capabilities are being so narrowly defined right now. IMO webpack should have no part in the native functionality of the SDK. We need the ability to retrieve arbitrary static assets based on http paths, without the client having to know anything about ICP. This should all work with native simple http requests.

A number of capabilities are currently missing as I see it:

  • ES/JS modules are impossible to use natively (only possible to use them with a bundler. Bundlers are not using ES modules under the hood, they compile them away)
  • Service worker issues like you mentioned (I’ll take your word for it)
  • RSS feeds, won’t be able to just do an http grab of files off of ICP
  • Building any type of frontend that isn’t loaded from a JS file directly. What if I want to have an html file as my entrypoint? Or a txt file?
  • http2/3 multiplexing
4 Likes

+1000

Agree with all the points. Especially the bit about having webpack in the sdk.

Also can we have the sdk as an npm package please? Or at least a wrapper. Would make it easier to create something like NextJS but for dfinity :wink:

2 Likes