Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example of communication with backend server for data #1295

Open
0pcom opened this issue Nov 10, 2024 · 12 comments
Open

Add example of communication with backend server for data #1295

0pcom opened this issue Nov 10, 2024 · 12 comments
Assignees
Labels
approved This feature request will be implemented enhancement A new feature request
Milestone

Comments

@0pcom
Copy link

0pcom commented Nov 10, 2024

Describe the feature

I really like the look and feel of cogentcore .

One use case I had in mind is as a framework for a webstore. Has such a use case been considered?

While it might work well for displaying a product inventory, keeping track of a shopping cart, etc. it won't be possible to actually integrate a payment into this without the ability to add arbitrary scripts used for stripe or other payment processors.

I'm unsure of the practicality of permitting scripts to be added to the web version of a cogentcore app. It would undoubtedly break the non-web version of the app or at least there would be a divergence in the behavior of the desktop vs web app.

If it were possible to easily or automatically convert javascript directly to golang webassembly, this might be a better route to take. However it's almost guaranteed to not work the same on desktop as in the browser even if that were possible.

If such a payment integration were possible, or an example existed, it would not be a difficult decision to use cogentcore for such an application in production.

Relevant code

No response

@0pcom 0pcom added the enhancement A new feature request label Nov 10, 2024
@kkoreilly
Copy link
Member

If you only need to support running on web, you could link arbitrary JS scripts in the index.html and call necessary JS functions using syscall/js. However, for cross-platform support, it would probably be easier to use a Stripe payment link. At some point, our htmlcore package will support JS to such an extent that you could manage everything directly in the app through that, but until then you can use one of the other two options. If you decide you want to do any of those options and need help implementing it, I can help you figure it out.

@0pcom
Copy link
Author

0pcom commented Nov 11, 2024

I am tempted to attempt one of those alternatives ; perhaps you are right that a payment link might be easier.

the only thing it appears will not be possible for the cogent web app is animation. But if, as you say, it is possible to include arbitrary scripts, then perhaps it may further be possible to include basically my existing animation wasm and run that alongside the cogentcore app?

The animation in question is somewhat similar to this:
https://0magnet.github.io/wasm-stuff/

It would be best if cogent core could directly support that type of animation

@kkoreilly
Copy link
Member

You could try using a canvas for the animation, which would be easier than trying to superimpose an existing wasm animation on an app.

@0pcom
Copy link
Author

0pcom commented Nov 11, 2024

ok I will see what I can do on it and file a ticket if I find any bugs. I sincerely appreciate your time in answering my questions

@0pcom
Copy link
Author

0pcom commented Nov 13, 2024

After spending some time playing with core, running some example apps, and building the desktop / web version of apps It is not immediately apparent if there is a way to do client / server web apps. The web view (core build web && core run web) compiles to basically static html with a (sizable) wasm binary.

Am I missing something?

I'm not sure that I explicitly need this for my current project (involving stripe payment integration) - though this is my current setup ; but in considering some of my other projects where a cogent core app might be useful or advantageous over the existing web interface, I would likely need a dynamic application or client-server connection. (Or to reconsider how I'm implementing this.)

Basically, there is some non-public data that the server filters in order to create a public view of the data - on both projects where I'm considering using cogent core. The server application looks at files on a disk which are not otherwise served as they exist. These files shouldn't be filtered on the client side or exposed publicly.

For both of these projects, the files in question are basically some .csv files where I don't want to show every column.

On the latter project, the server side may interact with a blockchain using external dependencies / cli interface (basically via os.Exec).

Both projects are currently self-hosted.

The size of the webassembly binary that core build web creates is much much larger than what is currently being served by either project, so I'm unsure it would be feasible to self-host this if I rewrite it to use cogent core, because of the increase in bandwidth usage. Which might be ok ; I might get by with hosting it on github. There are just some significant trade-offs to consider.

I like a dynamic server, self-hosted approach because the data being viewed can 'live update', i.e. any changes made on the csv will basically be immediately reflected on the web interface.

Your insights are sincerely appreciated, thanks.

@kkoreilly
Copy link
Member

Thank you for asking about this. Cogent Core apps are served statically, but that does not limit your ability to interact with a dynamic server.

For example, based on your situation, I would recommend serving the wasm binary on GitHub Pages or some other static site host, and then separately hosting a dynamic server that you make http requests to. You can easily use the standard http library or any other http request package to send requests to your server from the Cogent Core app and then use that http response data to populate the GUI. In that sense, Cogent Core serves the role that HTML/CSS/JS would normally serve, and then you still have a separate server that you make requests to.

So, for example, you could have an example.com/api/getInfo API endpoint that you host using a separate dynamic server, and then you make requests to that endpoint in Cogent Core, parse the CSV, and display it in a table. You could also have some streaming API endpoint where you leave the connection open to get live data updates.

In other words, you can have a client-server connection where the client is Cogent Core and the server is hosted separately. If you want, you could also host the Cogent Core app files on the same server, since they are just static files that you can easily serve, but there is no advantage to that over using a separate static site host.

In terms of the wasm binary size that you mentioned, we are working on reducing that (#733), with a future transition to GopherJS likely to cause significant size reductions (#974).

Please let me know if you have any other questions or concerns.

@0pcom
Copy link
Author

0pcom commented Nov 21, 2024

Ah ok, that makes a lot of sense.

So it should be noted that basically any cogent core application needs to target the wasm context. So you can't have both the desktop and the web version of a cogentcore application and use "os" standard library (or "syscall", "reflect" or "unsafe", and some others). At least not in the same application.

But then, the desktop gui version of the cogentcore app, which doesn't necessarily need to avoid those libraries would either be written to use them and maintained as a separate source (defeating the purpose of only coding once) or else they would still use basically the same backend server application (which does not have the library restriction) to communicate with as the webassembly version - making it essentially a two-part or client / server application.

However, that seems a bit tricky to configure in a flexible way, for the desktop gui app, without using os.Stdin at some point to parse the flag where you set the port where the application will try to connect to the daemon or server side of the running on localhost. It would basically have to serve on a fixed interface, or else a domain, which may not be ideal for all situations (or even for testing.)

your thoughts on this are appreciated.

@kkoreilly
Copy link
Member

Almost all functionality present in os, reflect, and unsafe works in wasm; only syscall is not possible. Therefore, almost all apps can be directly run on all platforms. There are some cases in which there needs to be desktop-specific code, but that can easily be placed in files with build tags while the main codebase remains cross-platform.

Based on the use case you described previously, you would still probably need a separate server for filtering the private data; if you give a client app on any platform direct access to private data, that doesn't really work. In terms of configuring access to that server flexibly, os.Stdin is a no-op on wasm, and env variables work but are not inherited from the server, so I would consider something like a config file (potentially in TOML, YAML, or JSON) that you embed into the app with //go:embed and read the config from. That embedded config file approach would work on all platforms.

If I am misunderstanding your question, please let me know.

@0pcom
Copy link
Author

0pcom commented Nov 22, 2024

Ok, that makes a lot of sense.

I'm not necessarily considering only my use case here, but broadly the limitations or special considerations for having both a desktop and wasm version of the same cogentcore app.

However, when you say this:

Almost all functionality present in os, reflect, and unsafe works in wasm; only syscall is not possible [...] There are some cases in which there needs to be desktop-specific code, but that can easily be placed in files with build tags while the main codebase remains cross-platform.

Unfortunately, the "os" package will return quite different based on the context where it's run. Essentially the behavior will not be the same between the webassembly version and the desktop version when using that package, despite the same program running on the same machine. So if it's required to write files to a disk or read them from a disk with the webassembly version of the application, that will need the server side application as a go-between. So it will work, but it does not work the same way.

I'm just stating some of these things as I realize them in hopes that it may someday improve the documentation for cogentcore.

The only thing I could ask for is an example - not specific to my purposes.

Just literally the simplest example of the (exact) same cogentcore application for both desktop gui and wasm that communicates with another server for it's backend data. That example, if it existed, might be a starting place for many people, and I believe it would make a good addition to your documentation.

For my immediate project(s), I will keep what I have for the moment, because it will be a substantial re-work to transition to using cogentcore and I think it will just take much longer to totally rewrite these than to make the minimal necessary changes that I need in the near term. However, I have no doubt it will reduce the codebase in the long run, to use cogentcore.

I do intend to investigate this more in the new year, and I hope to come up with a cogent core version of one or more of my projects. There is too much promise in this platform to simply dismiss the potential here (or to fail to pursue it). And I see that it's very actively developed and maintained - and well supported, with many improvements planned!

Sincere thanks for answering my questions, and for all the work you have obviously poured into this elegant platform.

@kkoreilly
Copy link
Member

Thank you for the response. Improving the documentation is definitely a high priority thing we need to do, and I agree it makes sense to provide an example of backend data fetching, so I will try to add that next week (I am currently doing a rewrite of our documentation structure and content).

There are definitely some cases in which the behavior of os will diverge on web compared to desktop, but for the specific case you mentioned, our jsfs package allows for os file operations to work directly on web without any server connection. (I will definitely document that soon).

Thank you for all of the feedback. The documentation and the framework as a whole should definitely be much improved in the new year.

@kkoreilly kkoreilly self-assigned this Nov 22, 2024
@kkoreilly kkoreilly changed the title Including javascripts for web? Add example of communication with backend server for data Nov 22, 2024
@kkoreilly kkoreilly added the approved This feature request will be implemented label Nov 22, 2024
@kkoreilly kkoreilly added this to the v0.4 milestone Nov 22, 2024
@0pcom
Copy link
Author

0pcom commented Nov 23, 2024

@kkoreilly Sincere thanks for your absolutely unrivaled support ; I'm excited to see the example when it has been included in the documentation, and to test the changes / improvements upcoming in the new year.

This is definitely a project to watch & follow closely.

@0pcom
Copy link
Author

0pcom commented Feb 5, 2025

Just to note, what prompts the need for backend server communication (for me / certain applications) is that in the webasembly context you can't do net.Dial - without basically using some custom library where you can do that in the webassembly context.

And also in the instance where you want your web GUI to be able to display files on the actual disk.. the core app code one writes would need to talk with this backend server.

I'm sure there are other cases worth mentioning.

Hope to see an example of this at some point!

...

I'm sure there are other cases worth mentioning.

There should be some strategy for app configuration which can be used the same way for all platforms where a cogentcore app is used.

suppose I have.. some golang vpn software which uses net.Dial and I want to use cogent core for the GUI.

And the typical invocation of the existing software is like this:

cli config gen -o /path/to/config.json #generate config file
visor --use-config /path/to/config.json #run the daemon using that config

Then, everything else is configured at runtime

  • It could work the same way as it does now on desktop.

  • It would need a separate backend in the instance that the web GUI is used, but could otherwise work the same

  • On mobile, In order for the same source code to work, the configuration would need to basically happen without explicitly generating a json config file beforehand & supplying the path to that file as an argument.

So it would be useful to have guidance or an overview of the strategy to use for actually making a somewhat complex cogentcore app work the same way on all platforms. Especially for people who have limited prior experience with developing golang mobile applications.

I suppose the main thing would be... to have the application start in lieu of a config and have an interface for setting up or customizing the config. Then, I suppose, save the config to disk and restart the app? Something like that?

Generally these are things you don't want to rely on if you want the app to work the same on all platforms (and you are using a separate backend):

  • flags
  • arguments

I'm almost certain there must be more things to avoid besides just flags and arguments.

If you aren't using a separate backend, the list is longer.

This would be really useful to document.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved This feature request will be implemented enhancement A new feature request
Projects
Status: Todo
Development

No branches or pull requests

2 participants