Amber Crystal Web Framework
As a web developer we all have flirt with the idea of having a the perfect web framework, one that is fun to work, that does not get in your way, catches bugs early, easily to scale, deploy anywhere and adaptable to different architecture patterns without sacrificing performance and difficult to learn.
Amber amberframework.org (http://amberframework.org/) takes an aim to address these pain-points by leveraging on Crystal Language features and converging a series of widely accepted features.
Amber is a web application framework written in Crystal. Amber makes building web applications fast, simple, and enjoyable with blazing fast performance.
Why Amber Framework?
Amber is a web application framework written in Crystal. Amber makes building web applications fast, simple, and enjoyable with blazing fast performance. Converging concepts and features that have been widely accepted by developers.
Here is why you should consider using Amber for your next project:
Crystal Language
Crystal as a programming language offers, a high level syntax with the performance and characteristics of a low level language.
- Syntax - Write a program with highly expressive with fewer lines of code. Easy to read without scarifying performance.
- Type System - Statically type checked, so any type errors will be caught early by the compiler rather than fail on runtime. Fewer bugs.
- Null Reference Checks - All types are non-nilable in Crystal, and nilable variables are represented as a union between the type and nil. Again fewer bugs.
- Macros - Crystal’s answer to metaprogramming is a powerful macro system, which ranges from basic templating and AST inspection.
- Concurrency Model - Crystal uses green threads, called fibers, to achieve concurrency. Fibers communicate with each other using channels, as in Go or Clojure, without having to turn to shared memory or locks.
Familiarity
Amber is very easy to learn and pick up. With a friendly and easy to read with Ruby-like syntax, Amber shares the same concepts as other popular web application frameworks that you find in other languages like Ruby, Express, Elixir, Laravel, making easy to understand and familiar to work with.
Performance
Amber is for programmers who want more performance, who enjoy working in a high-level scripting, combining native execution speed and concurrency so you will feel right at home, without losing your joy in programming because of code complexity.
02:28:43 Request | Started 2018-01-07 14:28:43 - 05:00
02:28:43 Request | Status: 200 Method: GET Pipeline: web Format: html
02:28:43 Request | Requested Url: /
02:28:43 Request | Time Elapsed: 94.0µs
Convergence of features
Amber developers did not stop with Crystal features, Amber converges features widely accepted from a broad series of web frameworks, sharing a lot of similarity with other web application frameworks widely used today, specially with Ruby On Rails.
Controller
While not a new concept at all Amber does not re-invent the wheel by having this concept Amber keeps the developer in familiar grounds.
class UsersController < ApplicationController
# Filters are methods that are run "before", "after" a controller action.
before_action do
# runs for specified actions
only [:index, :world, :show] { increment(1) }
# runs for all actions
all { increment(1) }
end
after_action do
# runs for specified actions
only [:index, :world] { increment(1) }
end
def index
@users = Users.all
render("index.slang")
end
end
Views Templates
Amber supports a wide range of templating languages, there are 4 different templating languages supported: slang, ecr, mustache, and temel. Since Crystal is a compiled language all view template are precompiled, at runtime, all templates are already loaded into memory, there’s no disk reads, complex file caching, or template engine computation involved, allowing your pages to render fast and feel snappy.
doctype html
html
head
meta name="viewport" content="width=device-width,initial-scale=1.0"
title This is a title
css:
h1 {color: red;}
p {color: green;}
style h2 {color: blue;}
body
ul
- @users.each do |user|
li = "#{user.name} - #{user.email}"
Pipelines
A pipeline is a series composable transformations throughout the connection life-cycle. We interact with pipes at every step of the connection life-cycle, and the core Amber components like Endpoints, Routers, and Controllers are all just Pipes internally. The basic idea of a Pipe is to unify the concept of a "connection" that we operate on. This differs from other HTTP middle-ware layers such as Rack, where the request and response are separated in the middle-ware stack.
Amber::Server.configure do |app|
pipeline :web, :auth do
plug Amber::Pipe::Logger.new
plug Amber::Pipe::Flash.new
plug Amber::Pipe::Session.new
plug Amber::Pipe::CSRF.new
end
pipeline :auth do
plug Authenticate.new
end
end
Parameters Validation
One of the most important aspects of validation is to prevent the widespread of invalid data in programs. Parameters Validations is your first line of defense, we can set a series of rules for data correctness for a given endpoint this allows you to decouple endpoint validations from the model and invalidate the request early before executing more demanding operations.
update_params = params.validation do
required(:name, "Your First Name is missing!") { |p| p.name? & !p.name.empty? }
required(:email, "Your email address is invalid!") { |p| p.email? & p.size.between? 1..10 }
required(:last_name) { |p| p.last_name? }
end
Routing
Amber defines routes explicitly in one central file for a couple of beneficial reasons. With the routes.cr file it is easy to understand at a high level which transformation are being performed for endpoints. Routes can be scoped to particular path, this is quite useful for representing API versions, CMS, Admin areas. Websocket routes are an exiting component, they allow to define full duplex communication channels over a single tcp connection with lower overhead, facilitating realtime data transfer form and to the server.
routes :web, "/pages" do
get "/about", StaticController, :about
resources "/posts", PostController
websocket "/chat", ChatSocket
end
Channels
All web-socket messages are routed through channels, and channel topics are where clients subscribe to listen for new messages. Channels define 3 public methods that can be used:
- handle_joined - Called when a user joins a channel.
- handle_message - Called when a user sends a message to a channel. A common message handler will simply rebroadcast the message to the other subscribers with rebroadcast! method.
- handle_leave - Called when a user leaves the channel.
class HomeController < ApplicationController
def index
ChatSocket.broadcast("message", "chat_room:123", "message_new", {"message" => "A new visitor!"})
render("index.slang")
end
end
ORM Agnostic
Amber by default comes with a active record pattern orm called Granite::ORM. You can configure different ORM adapters to Amber since Amber models layers is not tied to Amber, you are free to use any of the Crystal available ORM Granite, Crecto, Jennifer and Lucky::Record
Amber Cli
Amber has a built in CLI tool, to make your life easier while developing applications.
Here is a list of the available commands:
- d, deploy - Provisions server and deploys project.
- db, database - Performs database maintenance tasks
- e, encrypt - Encrypts environment YAML file. [env | -e --editor | --noedit]
- x, exec - Executes Crystal code within the application scope
- g, generate - Generate Amber classes (Controller, Migrations, Views, Models, Mailer, etc)
- n, new - Generates a new Amber project
- routes - Prints all defined application routes
- w, watch - Starts amber development server and rebuilds on file changes
System Tests
Amber was built with testing in mind. Amber made it as simple as possible to have your system specs. Having a built in system test framework that runs consistently and faster than other frameworks.
class SomeFeature < GarnetSpec::System::Test
scenario "user visits amber framework and sees getting started button" do
visit "http://www.amberframework.org"
timeout 1000
click_on(:css, "header a.btn.btn-primary")
wait 2000
element(:tag_name, "body").text.should contain "Introduction"
end
end
The Amber Framework team has work tirelessly on this project would like to encourage you to give Amber Framework a test run and see for yourself what value it brings to you as an engineer and to your organization.
amberframework.org (http://amberframework.org/)
Top comments (2)
Opening a discussion:
Amber and Crystal immediately reminded me of Phoenix and Elixir ...
Crystal, Elixir = Ruby-like, with better performance and/or language features
Amber, Phoenix = Rails-like, with less magic, better concurrency, etc
How would they stack up against each other, anyone has experience with both?
(don't even get me started about client side development, apart from ES6 and Typescript we have options like Elm, ReasonML, Dart, etc etc ...)
@leob is a little too early to compare Amber to Phoenix.
Both Phoenix and Amber are web frameworks, and when it comes to compare them you really have to compre the languages. Amber for those coming from a Rails background would probably be much easier to work with since Amber feels very Rails like. While Phoenix unless you know and understand Functional programming there is a learning curve. Phoenix has a great and mature community and new concepts, Amber is still getting there. Amber also has new concepts that you need to learn, Crystal because of its type inference makes you think different when writing code and this is something that Amber inherits from the language.
Another interesting aspect is one fundamental difference between Crystal and Elixir the two language have different programming paradigm OOP and Funtional and this difference, besides language specific features, is a detail to carefully consider when choosing Phoenix over Amber or viceversa for a particular project.
You should definitely give Amber a try, the community is welcoming and very friendly.