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