dropbear-software / todart Goto Github PK
View Code? Open in Web Editor NEWExample full stack Dart research project of a very over engineered Todo list application
License: MIT License
Example full stack Dart research project of a very over engineered Todo list application
License: MIT License
Right now Cloud Code isn't super well set up for things like Dart out of the box. However, it seems like it does have good support for easily extending it to meet your own development patterns and app templates for example as outlined here https://cloud.google.com/code/docs/intellij/create-app-from-custom-sample
Logically, this repository actually has 3 parts that are currently all bundled together but in reality probably shouldn't be. Instead consider splitting things out as follows:
1. A fully containerised development environment
The goals of this are that so long as I can run a container on my host machine or I have access to Github's Codespaces I have zero other requirements and can have a fully consistent development environment on any machine with all of the tools that I need. This for example would include tools like Cloud Code VSCode extension which in turn contained things like kubectl, skaffold etc.. It would also have it's own docker-in-docker / minikube support so I actually end up with a fully containerised k8's local development environment which seems pretty powerful and allows me to do that without a lot of sharp edges since everything would be standardised.
2. A application template for Fullstack Dart applications
Right now I have a very specific vision of what that means and looks like but it wouldn't be some huge challenge to fork it and say swap out gRPC for Cloud Functions if you wanted a different flavour of "Fullstack Dart".
3. The todart application itself
This is a specific instance of a "Fullstack Dart" application that happens to use the application template from Step 2 and is run inside of a standardised development environment from Step 1.
That already allows for a much nicer separation of concerns and helps lower the chances of creating a Frankenstein project. Additionally, it really opens up the ability for others in the community to start playing around with and experimenting with "Fullstack Dart" on top of what I hope is a really solid set of foundations.
I had previously installed this manually. Need to ensure it's there by default in the devcontainer
Unfortunately, gRPC doesn't currently work in the browser and won't be a native option before WHATWG Streams are finalized and implemented in all browsers and the relevant client side libraries are written.
Until, then we have a protocol that is extremely similar called gRPC-web which DOES work in browsers. However, our server doesn't know how to speak gRPC-web and as such we need something to help us translate between the two protocols.
In the long term as we get ready to move this project into a production environment we are going to be using a popular proxy that sits in front of our server called Envoy which is capable of doing just that and much more.
However, since we are building a Flutter web app in this project that means we will also need to run that same proxy in our development environment whenever our Flutter app wants to communicate with our server.
This task is to ensure that Envoy is automatically installed in our development environment and that it is configured to work with our application without any manual work on the developers behalf.
Currently the build script is just a handwritten Makefile but I would like to move to something a bit more cloud native in the form of Cloud Build. However, I want to have a smooth local development environment that isn't tied to a remote build server that also costs money to run so ensuring we have the ability to run it locally and for free is important.
Guidelines on how to do it can be found here: https://cloud.google.com/build/docs/build-debug-locally however, it requires Docker to run which means we will need a Docker in Docker setup for our devcontainer environment.
Currently we try to install the plugin via the Dockerfile using this line:
RUN /home/${USERNAME}/.local/flutter/bin/dart pub global activate protoc_plugin
However, this runs as root and when you try to use it on booting the container you will get an error message like so:
protoc-gen-dart: Plugin failed with status code 1.
Investigate other methods like the devcontainer.json postCreate commands for example.
Should be able to run a simple hello world demo remotely using Codespaces.
When running the devcontainer locally (i.e. not in codespaces) I get an error due to a permissions issue where the workspace directory I am working with is owned by the root
user rather than the codespace
user I am logged in as.
This is easy enough to fix by just running the following command in the root directory /workspaces/todart
but shouldn't be necessary:
sudo chown -R ${USER}: ${PWD}
Still exploring what exactly this is going to look like but probably something like Skaffold and minikube to build the local development environment using the exact same primitives that you would use in other environments like staging and production.
At the moment whenever we have to use tools like Envoy we are manually installing the binary inside the devcontainer which already feels like both a lot and completely detached from how you would work with it in every other environment. There is a super high liklihood that as this project matures we are going to end up using other sidecar style functionality with things like Dapr for example and I would rather learn the correct patterns once and use them consistently.
I've already done a small demo of this concept playing around where I was able to launch the server and Envoy using a simple skaffold dev
command but it was done is a particularly bad way, I couldn't actually connect to the Envoy proxy using the Flutter app or the native gRPC client in the common/examples/client.dart
file so there is still a bunch of debugging left to do which I suspect is going to require at least a bit deeper of a dive into Kubernetes land than I had originally planned on but is probably kind of inevitable on a long enough timeline because my original plan for everything in a single container that I throw to Cloud Run is already starting to feel like kicking the can down the road so I may as well lean into it early on in the process where the rest of the complexity is already fairly low but will only get worse over time.
In the meantime I came across this repository which isn't exactly what I am looking for but does have something similar to what I had in mind that I am sure I can learn from https://github.com/mhamrah/grpc-example
Resources:
Unsure of exactly what I want in terms of capabilities yet but I found some good starting points here https://github.com/kevmoo/knarly_vote/blob/main/.github/workflows/dart.yml in the knarly_vote repo
As an example when you take a look at the ProjectsListView
widget you will find code like this:
Widget _showProjects(BuildContext context, List<Project> projects) {
return ListView.builder(
itemCount: projects.length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
GoRouter.of(context).go('/project/${projects[index].resourceName}');
},
child: Padding(
padding: EdgeInsets.only(top: index == 0 ? 12 : 0, bottom: 12),
child: _projectCard(context, project: projects[index]),
),
);
},
);
}
Which says when a user taps on this widget, send them to this new route.
This forces my widget to take a dependency on the go_router
package which seems like a lot. I'm not sure what the correct Flutter way would normally be to handle this but in other frameworks I have played around with like Lit the recommended approach here would be to make use of the browsers native event model and just fire an event that says something like the user clicked this particular widget which would bubble up the tree and another class would be responsible for saying listen for this particular kind of event and whenever you receive one then do this particular bit of logic (i.e. send them to the new page)
So now in that scenario the widget would not have this unnecessary dependency on the router any more. It would just take in a ListProjectsResponse
(independently of how that was gotten i.e. so no networking concerns to worry about) and is just responsible for firing events
.
My quick bit of Googling suggests some things here might be helpful like Streams and I even got the impression that this was literally the foundation that a bunch of state management solutions were built on top of like Bloc and possibly even Riverpod?
Anyways, take a look at what is out there that would make this possible and figure out a way to remove this dependency if possible.
Install the protoc compiler and the relevant Dart plugins. Test that you can generate relevant files from a proto file.
Running make server
doesn't currently work on a fresh devcontainer as the developer would need to run dart pub get
to fetch the relevant dependencies first.
Some potentially helpful resources:
The following test is currently failing. Suspect the bug lies somewhere in this method
test('Validates its own toReadableString method correctly', () {
final identity = CloudResouceIdentity();
expect(CloudResouceIdentity.isValid(identity.toReadableString()), isTrue);
});
I currently have a test set up which takes a known good value for the string 'Hello World' that is converted to Crockford Base32 according to this calculator https://www.dcode.fr/crockford-base-32-encoding (including the checksum character as required for validation).
There is a test set up for this here which is currently failing. It is almost certainly related to the same bug that is outlined in issue #20
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.