amberframework.org

As web developers, we all have flirted with the idea of having the perfect web framework — one that is fun to work with, does not get in your way, catches bugs early, is easy to scale, easy to learn, deployable anywhere and adaptable to different architecture patterns without sacrificing performance.



Amber takes an aim to address these qualms by leveraging on Crystal Language and converging a series of widely accepted features.

Amber is a web application framework written in Crystal, which makes building web applications fast, simple, and enjoyable with blazing fast performance.

Here are a few good reasons to give it a try:

1. 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, yet more simplistic code that is easy to read without scarifying performance.

— Write a program with highly expressive, yet more simplistic code that is 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 run-time. Fewer bugs.

— Statically type-checked, so any type errors will be caught early by the compiler rather than fail on run-time. 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.

— 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 meta-programming is a powerful macro system, which ranges from basic template to Abstract Syntax Tree inspection.

— Crystal’s answer to meta-programming is a powerful macro system, which ranges from basic template to Abstract Syntax Tree 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.

2. Extremely low learning curve

Amber is very easy to learn and pick up, with a friendly and easy to read Ruby-like syntax. Amber shares the same concepts as other popular web application frameworks that you find in other languages like Ruby, Express, Elixir and Laravel, making it easy to understand and familiar to work with.

3. Blazing fast performance

Amber is for programmers who want more performance, who enjoy working in a high-level scripting environment, with combine native execution speed and concurrency, without sacrificing 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

4. Convergence of features

Amber developers did not stop with Crystal features. Amber converges a wide range of accepted features from a broad series of web frameworks, especially with Ruby On Rails.



Controllers

Amber does not re-invent the wheel. It keeps you in familiar territory by embracing Model-View-Controller patterns and Convention over Configuration principles.

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 template languages. There are 4 different template languages currently supported: Slang, ECR, Mustache, and Temel.

Since Crystal is a compiled language, all view templates are pre-compiled. At run-time, all templates are loaded into memory. There are no disk reads, complex file caching, or template engine computation involved, allowing your pages to render swiftly.

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 of transformations throughout the request life-cycle. Each request interacts with a “pipe” at every step of the request. This differs from other HTTP middleware layers, where the request and response are separated in the 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 issue of invalid persisted data in programs.

Parameters Validation is your first line of defense. We can set a series of data correctness rules for a given controller-action. This allows for the separation of controller-action validation from model validation, by invalidating the request at an early stage preventing the execution of 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. With the routes.cr file, it is easy to understand at a high level which transformations are being performed for each controller-action.

Routes can be scoped to a particular path. This is quite useful for representing: API versions, CMS, Admin areas, etc.

Web-sockets routes represents a full duplex communication channel over a TCP connection with low overhead, facilitating real-time data transfer form and to the Amber 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. A channel represents a topic. Clients subscribe to a Topic send and receive new messages. Channels define 3 public methods:

handle_joined - Called when a user joins a channel.

- 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.

- Called when a user sends a message to a channel. A common message handler will simply rebroadcast the message to the other subscribers with 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

Object-Relational Mapping Agnostic



Amber model layer is not tied to any specific object-relational mapping library Instead it provides a default active record pattern ORM called Granite::ORM, for quick prototyping.

The developer is free to configure and use any of the Crystal available Object-Relational Mapping library available: Granite, Crecto, Jennifer, Lucky::Record, Active Record. This allows you to select the right tool for your project, without Amber get in your way.

require "granite_orm/adapter/sqlite" class Comment < Granite::ORM::Base

adapter sqlite



has_many :posts table_name comments

field name : String

field body : String validate("Invalid Comment.", ->(comment : self) {

(comment.name != nil && comment.name != "") || (comment.body != nil && comment.body != "")

})

end # Querying # ORDER BY Example

posts = Post.all("ORDER BY created_at DESC") # JOIN Example

posts = Post.all("JOIN comments c ON c.post_id = post.id

WHERE c.name = ?

ORDER BY post.created_at DESC",

["Joe"])

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.

— Provisions server and deploys project. db, database — Performs database maintenance tasks

— Performs database maintenance tasks e, encrypt — Encrypts environment YAML file. [env | -e — editor | — noedit]

— Encrypts environment YAML file. [env | -e — editor | — noedit] x, exec — Executes Crystal code within the application scope

— Executes Crystal code within the application scope g, generate — Generate Amber classes (Controller, Migrations, Views, Models, Mailer, etc)

— Generate Amber classes (Controller, Migrations, Views, Models, Mailer, etc) n, new — Generates a new Amber project

— Generates a new Amber project routes — Prints all defined application 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 and provides a built in System Test framework that runs consistently and fast.

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

5. Fast Prototyping and Scalability

Web application performance and Scalability are of huge importance when developing a business around internet services especially when we talk about driving more traffic, engagement, and increase brand loyalty. What’s more is slow downs and/or downtime can cost companies thousands of dollar.

Amber has some benefits to overcome these issues:

Global type inference. You can program without type annotations except for a few cases where you are required to do so (generic type arguments). Amber still recommends to use types

Amber allow for very quick prototyping, similar to dynamic languages. You can scaffold a project in 7 steps without touching one line of code.

Amber gives you a high throughput with with no premature optimizations, and sub second response times.

Thanks to Crystal, Amber has a low consumption of CPU, Memory, and disk space.

Distributed binary — All amber projects compile to a binary that can be easily distributed. This makes deployments fast and easy.

Catch bugs early. Programs are verified by before they can be executed. This rules out many programming errors Null reference checks to name one.

Where to start?

What you’ve seen here just barely scratches the surface of what Amber Framework can do. There’s so much more to help you build, organize, and scale your web applications. To start coding yourself, I’ll recommend following resources.

Lastly I must thank the Crystal and Amber Community for your support and contributions.