Add a blog post about dot dot vote

I don't like the structure of the blog post or lack of narrative, but I just
need to get this published to move on to what's next :)
This commit is contained in:
R Tyler Croy 2020-10-20 20:31:00 -07:00
parent b52cc595a5
commit 853386d78b
No known key found for this signature in database
GPG Key ID: E5C92681BEF6CEA2
3 changed files with 128 additions and 0 deletions

View File

@ -0,0 +1,122 @@
layout: post
title: Quick and simple dot-voting with Dot dot vote
- rust
- dotdotvote
I recently launched [Dot dot vote](, a simple web
application for running anonymous dot-voting polls. Dot-voting is a quick and
simple method for prioritizing a long list of options. I find them to be quite
useful in when planning software development projects. Every team I have ever
worked with has had far too many potential projects than they have people or
time, [dot voting]( can help customers
and stakeholders weigh in on which of the projects are most valuable to them.
[Dot dot vote]( makes it trivial to create
short-lived polls which don't require any user registrations, logins, or
![Dot dot vote](/images/post-images/2020-dotdotvote/ddv-poll.png)
The desire for the application came out of some of my own roadmap planning
exercises for [Scribd](https://tech.scrib.domc). Unfortunately I didn't finish
the application in time and had to hack together something unpleasant with
Google forms. Next time around, the tool will be ready!
Give it a try and let me know what you think!
## Technologies
Dot dot vote is [free and open source
software](, and is quite simple. The
backend is built with [Rust]( using the minimalistic
[Tide]( web application framework and
[sqlx]( for database (PostgreSQL) access. The "frontend" is plain old HTML and some basic JavaScript being rendered via [handlebars-rust](
The application is currently deployed on Digital Ocean's new "App Platform",
which I won't discuss in this blog post except to say that it is _interesting_
in both good and bad ways.
> "this might be the most complete/functioning oss tide app in existence"
> -- Co-maintainer of Tide
This isn't my first Rust application which has reached "production" status,
[hotdog]( deserves that honor. It is
however the first non-trivial web application I have built from top to bottom
in years. Much of the time spent on implementation was just getting familiar
with the tools. With that experience under my belt, I actually built another
(non-public) web application of similar scope in about a day of frenzied
coding; Rust is web-ready as far as I am concerned!
There are a couple tips I would like to share for anybody wishing to explore
using these tools for their own projects.
### cargo sqlx prepare
I made heavy use of the `query!` and `query_as!` macros in sqlx, which both do
compile-time SQL query syntax validation against your live database schema.
It's *incredibly useful*, but it has the downside of requiring a live database
connection for in CI and other builds.
The experimental
[sqlx-cli]( has an
integration with cargo that allows you to generate a `sqlx-data.json` file
which the macros can use instead of a live connection.
Despite being experimental and arguably a bit bleeding edge, I had no issues
with using the latest `master` branch from sqlx.
### handlebars-rust template reload in dev
Dot dot vote uses the `register_templates` call in handlebars-rust to load the
templates in the `views/` directory. For obvious performance reasons this reads
everything once, compiles, and stores the templates in memory. In development
this is *not* very useful, since you have to restart the web server any time
you make a minor view change.
The approach that I took was to provide a `render()` function on the `AppState`
struct which would abstract Handlebars template rendering for the routes. Then, in order to allow for "reloading" of templates in development/debug builds, I used the following snippet:
pub async fn register_templates(&self) -> Result<(), handlebars::TemplateFileError> {
let mut hb = self.hb.write().await;
hb.register_templates_directory(".hbs", "views")
pub async fn render(
name: &str,
data: &serde_json::Value,
) -> Result<tide::Body, tide::Error> {
// Reload all the templates in debug builds on each render call
// etc
Overall the project was fun exploration into the web world of Rust. I would
strongly recommend the Tide/sqlx/handlebars-rust stack for building small and
fast API and web services. The stripped release binary is ~4MB and only takes
up 30MB at runtime in production. The most basic tier in Digital Ocean is
**way** over-provisioned!
With this little side project "complete", it's back to other fun Rust hacking!

Binary file not shown.


Width:  |  Height:  |  Size: 41 KiB

tag/ Normal file
View File

@ -0,0 +1,6 @@
layout: tag_page
title: "Tag: dotdotvote"
tag: dotdotvote
robots: noindex