Give Codeship’s CI/CD Platform a Try

Want to learn more?

In this article, we’ll implement and deploy a Gotham full-stack web framework using the Tera template system, Webpack for a complete front-end asset management, a minimal VueJS and CoffeeScript web app and deploy to Heroku. Gotham is a Rust framework which is focused on safety, speed, concurrency and async everything. Webpack is a NodeJS website asset preprocessor and bundler which can let you use any of your favorite front end technologies. Combining these technologies allow for a small footprint on the server, which means saving money on infrastructure, very fast performance in page load for higher visitor retention and the full flexibility of client side code available to you for web design without limitations.

Because there is a lot to unpack here, this article will cover a step-by-step guide to launch these features on Heroku and advise you on common issues that need to be considered.

Now whenever you run the cargo command to build your project, it will verify your dependencies, bundle and prepare your assets. This is very helpful when you deploy to Heroku as it will tell you which dependencies are missing.

A working project

The hello world example given on the main page for Gotham is as follows. Put this in your src/main.rs file.

At this point you can run cargo run and use your browser to navigate to http://127.0.0.1:7878 to see the hello world example.

From here we’re going to remove the const HELLO_WORLD line and the entire say_hello method. We’ll add a method named index_page, add a method named router, and we’ll update the last line of main method to use them.

This changes introduce mime type support in the method which we now use a router to get to. The router is mapping any request to the root url / to the index_page method.

For this project we’ll follow Rails’ outline for organizing the files for the site.

Now to demonstrate how to serve static assets in Gotham. Create the following directory structure app/assets/stylesheets in the root of your project. Create a file in that last directory named application.css and give it some styles like so.

This will route any requests that try to access the style/ path in the url to any file that’s in app/assets/stylesheets. In our HTML code we’ll link to this style directly. Before that though you can now try to load the url http://127.0.0.1:7878/style/application.css after you run cargo run and see the styles we’ve entered in.

We’re now ready to introduce HTML pages with the Tera templating system.

Tera templating in Gotham

Tera is a templating DSL for Rust which serializes Rust objects before processing the views. There’s very little learning curve to using it as it is designed with common template tasks in mind.

We’ll rewrite the index_page method to now use Tera and include the stylesheet we’ve created. Also we’ll create a core object to load all our templates from and provide it with a path for our views. In your src/main.rs file update it for the following.

In the lazy_static! block we create the TERA object which will load all the views and templates into an internal hash like lookup system and by which we will use it to render views with given contexts. The context we provide a view will contain the objects the view are to be updated or generated with.

Now we need to create our application template and our landing page for the above code to work. Create the file app/views/layouts/application.html.tera

The block and endblock tags allow you to place default page content into each section while also allowing any pages that inherit this template to optionally overwrite it, or even add to it by calling super first. The for loops above use a value provided from context insertion from our code — and those must exist. The for loop then iterates over the collection of items provided and can be used to insert text internally with the {{ }} syntax.

Now let’s create the index page that inherits from this. Create the file app/views/landing_page/index.html.tera and place the following in it.

Here we use Tera’s extend keyword to choose the template we wish to employ and then we replace to blocks from the template, title and content. Go ahead and spin up the server and try it out; cargo run and navigate your browser to http://127.0.0.1:7878. You have now successfully deployed templating.

Adding VueJS and CoffeeScript support

Most of the tooling for this was done when we added the webpacker crate, installed WebpackerCli, and added build hooks in the build.rs code. We have three parts now to do

Routing for the Webpack’d assets

Implement helper methods for looking up assets from the manifest

Install and configure the Webpack dependencies for VueJS & CoffeeScript

Routing is simple as we will be following the same technique we used for our stylesheet earlier. We’ll set our webpack’d assets routing url path to a globally available static value for convenience should we ever desire to change it. In our src/main.rs file add:

This creates a hash lookup table for each of our assets that Webpack has preprocessed and prepared. Now let’s add our helper methods to simplify getting a full routing path from a given file name. In src/main.rs add the following.

When Webpack processes CoffeeScript files the result will be a JavaScript file so we can give our helper method the original filename example.coffee and it changes it to example.js as the key to lookup from the file manifest which then gives us a full path such as /packs/example-779d5e71ab17b09de712.js and that source path gets inserted into our webpage providing both pre-processing and cache invalidation. The same thing also occurs with stylesheets from SASS files to CSS. Using these helper methods to provide the full link path to our web document source references provides an up to date code experience for the end user.

Now that we have our asset file manifest helper methods we can include the default JavaScript script that Webpacker added by changing the sources line in our index_page method to the following:

let sources = &[&asset_source("application.js")];

Now when you run your program with cargo run you can look at the source code of the page and it now includes a valid script inclusion for a versioned application.js file.

Now that the second step is done let’s do the third step of installing and configuring CoffeeScript and VueJS for Webpacker. Ideally you can just run webpacker-cli install:vue and webpacker-cli install:coffee. This will create the configuration files for you but be sure to pay attention as to whether the Yarn dependencies are installed. As of this writing VueJS dependencies are requiring you to manually select the version number for vue-loader. The output displays the command you should run to add the Yarn dependencies.

If you want to manually install VueJS then you could do it as follows. Run

yarn add vue vue-loader@15.4.2 vue-template-compiler

Create the file config/webpack/loaders/vue.js and write in the following.

Add the above after webpacker is included and before the module exports line. And that’s how easy it is to manually add support for something to Webpacker. Now whenever you write VueJS code in your app/javascript/packs folder you can include it with the _pack helper methods we wrote earlier.

VueJS and CoffeeScript example

The install command for WebpackerCli creates some examples under both app/javascript and app/javascript/packs. We will use the app/javascript/app.vue example as it is and if you didn’t generate one with the install command here it is below:

In my experimentation the environment JavaScript detects it keeps reporting production regardless of changing local environment variables so if you’d like to use the VueJS Devtool addon for your browser you should uncomment the devtools line above while you work.

Now that we have the code to test we need only to include it in our site. Let’s change our styles and sources values in the index_page method in src/main.rs to the following:

We’re including both the script and style for our VueJS code by using our _pack method helpers for the hello.coffee file. Now add the following to app/views/landing_page/index.html.tera within the content block.

<div id="vue-app"></div>

And now you have a working VueJS & CoffeeScript app when you run cargo run and view http://127.0.0.1:7878 .

Deploying to Heroku

To deploy to Heroku you will need to use three separate buildpacks together for NodeJS, Ruby, and Rust. First let’s initialize Heroku in our project. Use the Heroku Cli tool:

The application won’t work on Heroku without binding to both the address 0.0.0.0 and the port number defined by the environment variable. Now to test it locally you have to assign a port number so the command in bash would look like PORT=7878 cargo run.

Next we have to let Heroku know what command to run to run the application. Open up a file name Procfile and place the following.

web: target/release/mouse

The last part is of course the name of the application which we gave it; mouse. Now you need only to commit the source code with git and upload it to heroku.

Be sure your .gitignore file has lines for node_modules and tmp as you don’t want to upload those.

git add .
git commit -m "Heroku ready"
git push heroku master

After time enough to brew coffee you can now open the deployed website with the command heroku open. And viola! You’ve achieved implementing and deploying a fullstack Gotham app.

As your application grows it will help to organize similar source code categories together in their own separate files (such as moving routing to src/route.rs).

Summary

This how-to should save you tons of time figuring out how to get a fullstack Gotham app ready. You can view the source code for this example here on Github.

What you have here is a quicker way to get up and going with a very fast and capable website. Fast being what Rust and Gotham bring to the table and capable being what Webpacker and the entire JavaScript ecosystem bring with it. When you use Rust for your website you get the best performance you can in delivery. Any slowness experienced will be from other factors like unoptimized database queries or network latency. It’s exciting to be working with both powerful and performant technologies when delivering content. Enjoy!

Additional resources

Subscribe via Email

Over 60,000 people from companies like Netflix, Apple, Spotify and O'Reilly are reading our articles. Subscribe to receive a weekly newsletter with articles around Continuous Integration, Docker, and software development best practices.

We promise that we won't spam you. You can unsubscribe any time.

Join the Discussion

Leave us some comments on what you think about this topic or if you like to add something.