Play the Retro Axis original theme song
Exploring Web Frameworks in 2020: D (Vibe.D), Crystal (Lucky), C# (Blazor)
31 Jul 2020 -
In this article, the following language (framework) will be quickly explored. You can click the language name to jump ahead:
There is an ever increasing number of web frameworks, and the choices can be overwhelming when trying to start from scratch. Deciding where to begin, often a developer will stick to the language and paradigm they are most familiar with. But what happens when the programming language and toolkits start to fall behind or are less popular than they used to be? Popularity is not always a reason to make a change, but when the toolchain and innovations are slowing, and many libraries have not received updates in several years, it is cause for concern. Technology changes quickly, so it is important to ensure whatever code you write can be easily updated and maintained for years to come without having to worry about the security or stability of dependencies.This is what happened to me recently, when looking to build a new application. In a previous article, I began creating a web framework based on JRuby with Roda. After producing a few successful small proof of concept applications, I was quickly overwhelmed with the task of back-porting improvements from my projects back into the framework. Also, I found that many dependencies and libraries have suffered from neglect or simply been abandoned. So… the hunt for a strong, community-supported, modern, and feature-rich framework begins.
Choosing a Programming Language
One important aspect of any framework is the programming language and runtime. This is where the list of choices and options can become daunting and many factors to consider, such as:
- differences between dynamic and static typed languages,
- is it compiled or interpreted
- 3rd-party or add-on library availability and ease of installing/maintaining
- what is the programming paradigms
- functional,
- object oriented,
- imperative
- The runtime tooling
- debugging
- compiler
- package manager
- Learning & Support
- Documentation : Guides, Tutorials, API
- Community Forums
- Blogs Posts, 3rd party websites, other articles
- Commercial support from a reputable vendor
- Platform Availability
- CPU Architectures (x64, aarch64, mips, riscv, etc)
- Operating Systems (linux, macosx, windows)
Programming Languages Explored
Taking the above factors into consideration, I began by examining industry trends. There are many opinionated lists but survey's are a great way to understand the market of a particular technology set:
What I found is languages like Ruby are on the decline, and have been trending downward for some time. The overall popularity of Rails has also fallen, despite it being a very mature framework. Another interesting fact is the list of loved and dreaded languages and frameworks. Javascript is one of the most popular, but ranks higher in dreaded than other languages. There are some languages that simply don't make these lists, yet have some compelling options.
C# (.Net) on Linux
Microsoft C# and ASP.Net have long been the development tools of choice for Windows Servers. An open-source Linux implementation called Mono was originally written by Novell and is still being updated. Recently, Microsoft has been heavily investing in making .NET Core available as a cross-platform toolkit running across more operating systems and processor targets. .NET itself runs on the CLR (Common Language Runtime), which, similar to the Java JVM, acts as the runtime component which runs the code. Both C# and F# are languages which run on the CLR. ASP.Net is a framework and set of libraries designed for developing web applications. C# is object oriented and type-safe. It can be used for creating many different types of applications including console, network, windows, UI, mobile an example. The syntax is C-like and easy to learn. The core library has a lot of capability and the .NET system also provides the management and addition of packages through the NuGet package system. While you can use any editor you wish, Visual Studio provides a significant boost in productivity and eases project management for .NET projects.
What does C# look like?
using System;
class BoxingExample
{
static void Main()
{
int i = 123;
object o = i; // Boxing
int j = (int)o; // Unboxing
}
}
ASP.Net
ASP.Net provides several options for starting a project. Running 'dotnet new' from the command line will display a list of project templates. Specific to web development:
% dotnet new
Templates Short Name Language Tags
----------------------------------------------------------------------------------------------------------------------------------
Razor Component razorcomponent [C#] Web/ASP.NET
Razor Page page [C#] Web/ASP.NET
MVC ViewImports viewimports [C#] Web/ASP.NET
MVC ViewStart viewstart [C#] Web/ASP.NET
Blazor Server App blazorserver [C#] Web/Blazor
Blazor WebAssembly App blazorwasm [C#] Web/Blazor/WebAssembly
ASP.NET Core Empty web [C#], F# Web/Empty
ASP.NET Core Web App (Model-View-Controller) mvc [C#], F# Web/MVC
ASP.NET Core Web App webapp [C#] Web/MVC/Razor Pages
ASP.NET Core with Angular angular [C#] Web/MVC/SPA
ASP.NET Core with React.js react [C#] Web/MVC/SPA
ASP.NET Core with React.js and Redux reactredux [C#] Web/MVC/SPA
Razor Class Library razorclasslib [C#] Web/Razor/Library/Razor Class Library
ASP.NET Core Web API webapi [C#], F# Web/WebAPI
ASP.NET Core gRPC Service grpc [C#] Web/gRPC
Protocol Buffer File proto Web/gRPC
Blazor
Blazor is a new technology based on Web Assembly. It removes the need to write JavaScript and allows you to program using C# instead. This is a very attractive feature as you can control the DOM natively with C#. It makes heavy use of Razor templates:
@page "/todo"
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private IList<TodoItem> todos = new List<TodoItem>();
private string newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
Combined with the Entity Framework ORM and MVC pattern, Blazor and ASP.net is a great option for starting new web projects.- - - - - -
D
D Language Programming from Digital Mars is a static typed, compiled, and is multi-paradigm, with a C-like syntax. D's history has a troubled and fragmented past. In the 1.0 days of D, the community fragmented between two core libraries. One was called Phobos, the default D library. It had some drawbacks and weaknesses, leading to a 3rd-party community supported library called Tango. When D 2.0 standard was announced, it effectively was incompatible with Tango, and many of the concerns around Phobos were addressed. Despite these early challenges, today D is a solid choice for building modern applications. There is a choice of compilers and variety of cpu and os targets supported. DUB, the official D package manager also provides additional capabilities that makes installing 3rd-party projects or dependency libraries easier. There are few IDE's and plugins for common editors available for D.
What does D look like?
<span arial="" helvetica="" sans-serif="" style="font-family:" tahoma="">import std.stdio : writeln;
void main()
{
if (1 == 1)
writeln(You can trust math in D);
int c = 5;
switch(c) {
case 0: .. case 9:
writeln(c, is within 0-9);
break; // necessary!
case 10:
writeln(A Ten!);
break;
default: // if nothing else matches
writeln(Nothing);
break;
}
}</span>
D Web Frameworks
The D Language site provides a catalog of libraries and applications, including a list of web frameworks and toolkits:- Vibe.D
Vibe.D
is the most mature and supported of the currently available D frameworks. It boasts a variety of Performance, Simplicity, and Productivity features. DiamondMVC also mentions using Vibe.D under the covers. View's can be rendered using Diet templates. An example of a Vibe.D web framework app.d file from their examples:
import vibe.http.router;
import vibe.http.server;
import vibe.web.web;
void main()
{
auto router = new URLRouter;
router.registerWebInterface(new WebInterface);
auto settings = new HTTPServerSettings;
settings.port = 8080;
settings.sessionStore = new MemorySessionStore;
listenHTTP(settings, router);
}
class WebInterface {
private {
// stored in the session store
SessionVar!(bool, "authenticated") ms_authenticated;
}
// GET /
void index()
{
bool authenticated = ms_authenticated;
render!("index.dt", authenticated);
}
// POST /login (username and password are automatically read as form fields)
void postLogin(string username, string password)
{
enforceHTTP(username == "user" && password == "secret",
HTTPStatus.forbidden, "Invalid user name or password.");
ms_authenticated = true;
redirect("/");
}
// POST /logout
@method(HTTPMethod.POST) @path("logout")
void postLogout()
{
ms_authenticated = false;
terminateSession();
redirect("/");
}
}
The corresponding 'Diet' Template file:
doctype 5
html
head
title Welcome
body
h1 Welcome
- if (authenticated)
form(action="logout", method="POST")
button(type="submit") Log out
- else
h2 Log in
form(action="login", method="POST")
p User name:
input(type="text", name="username")
p Password:
input(type="password", name="password")
button(type="submit")
Crystal
Crystal is a relative newcomer to the scene of languages. Inspired heavily by Ruby, Crystal is a compiled language and statically typed. A package manager, called Shards, is available to resolve dependencies. Because it is compiled, there is a huge reduction in developer time spent on writing tests and debugging as the compiler helps to identify defects and run checks. Platform support for crystal is available for x64, aarch64 and a few others, with Tier 1 & 2 support for MacOS, Linux and BSD. While crystal is still maturing, it has great potential and a growing ecosystem forming quickly.### What does Crystal look like?
require "socket"
def process(client)
client_addr = client.remote_address
puts "#{client_addr} connected"
while msg = client.read_line
puts "#{client_addr} msg '#{msg}'"
client.puts msg
end
rescue IO::EOFError
puts "#{client_addr} disconnected"
ensure
client.close
end
server = TCPServer.new "127.0.0.1", 9000
puts "Listening on 127.0.0.1:9000"
loop { spawn process(server.accept) }
Lucky Web Framework
Lucky is a from-scratch framework written for Crystal. While not yet achieving a 1.0 release, Lucky's feature set is very rich and has many of the necessary building blocks for getting a web application up and running quickly. The command line tool provides generators, database management, subcommands for running the system, and more. It includes an ORM called Avram which can be used without Lucky. At present, Avram only supports Postgresql, but the documentation indicates you can use other databases using alternative libraries. Avram provides migrations, queries, and models. Starting a lucky project is quick simply by running lucky init
. From the main webpage, here is an example of lucky rendering an HTML view for a user:
class Users::Index < BrowserAction
get "/users" do
users = UserQuery.new.sorted_by_last_name
html IndexPage, users: users
end
end
class Users::IndexPage < MainLayout
needs users : UserQuery
def content
ul class: "users-list" do
@users.each do |user|
li { link user.name, to: Users::Show.with(user) }
end
end
end
end
Other Languages & Frameworks
While writing this article, I explored several other noteworthy programming languages and web frameworks. I am linking directly to the framework page, which provides enough context about the language.
Wrap-Up
Choosing a web framework requires research, experimentation, patience, and learning. While I am yet to select a framework, I have spent the most time enjoying working with C# (Blazor) and Crystal (Lucky). More learning and understanding of these languages the framework API's is required before I can become fully productive.