Serverless was first used to describe applications that significantly or fully
depend on 3rd party applications / services (‘in the cloud’) to manage server-side
logic and state.
‘rich client’ applications (think single page
web apps, or mobile apps) that use the vast ecosystem of cloud accessible
databases (like Parse, Firebase), authentication services (Auth0, AWS Cognito),
etc.
Serverless can also mean applications where some amount of server-side logic
is still written by the application developer but unlike traditional architectures
is run in stateless compute containers that are event-triggered, ephemeral (may
only last for one invocation), and fully managed by a 3rd party.
‘Functions as a service
AWS Lambda is one of the most popular implementations of FaaS at present,
A good example is
Auth0 - they started initially with BaaS ‘Authentication
as a Service’, but with Auth0 Webtask they are entering the
FaaS space.
a typical ecommerce app
a backend data-processing service
with zero administration.
FaaS offerings do not require coding to a specific framework or
library.
Horizontal scaling is completely automatic, elastic, and managed by the
provider
Functions in FaaS are triggered by event types defined by the provider.
a FaaS-supported message broker
from a
deployment-unit point of view FaaS functions are stateless.
allowed the client direct access to a
subset of our database
deleted the authentication logic in the original application and have
replaced it with a third party BaaS service
The client is in fact well on its way to becoming a Single Page Application.
implement a FaaS function that responds to http requests via an
API Gateway
port the search code from the Pet Store server to the Pet Store Search
function
replaced a long lived consumer application with a
FaaS function that runs within the event driven context
server
applications - is a key difference when comparing with other modern
architectural trends like containers and PaaS
the only code that needs to
change when moving to FaaS is the ‘main method / startup’ code, in that it is
deleted, and likely the specific code that is the top-level message handler
(the ‘message listener interface’ implementation), but this might only be a change
in method signature
With FaaS you need to write the function ahead of time to assume parallelism
Most providers also allow functions to be triggered as a response to inbound
http requests, typically in some kind of API gateway
you should assume that for any given
invocation of a function none of the in-process or host state that you create
will be available to any subsequent invocation.
FaaS
functions are either naturally stateless
store
state across requests or for further input to handle a request.
certain classes of long lived task are not suited to FaaS
functions without re-architecture
if you were writing a
low-latency trading application you probably wouldn’t want to use FaaS systems
at this time
An
API Gateway is an HTTP server where routes / endpoints are defined in
configuration and each route is associated with a FaaS function.
API
Gateway will allow mapping from http request parameters to inputs arguments
for the FaaS function
API Gateways may also perform authentication, input validation,
response code mapping, etc.
the Serverless Framework makes working
with API Gateway + Lambda significantly easier than using the first principles
provided by AWS.
Apex - a project to
‘Build, deploy, and manage AWS Lambda functions with ease.'
'Serverless'
to mean the union of a couple of other ideas - 'Backend as a Service' and
'Functions as a Service'.
"DistributedLog (DL) is a high-performance, replicated log service, offering durability, replication and strong consistency as essentials for building reliable distributed systems.
"
Create an additional staging environment that closely resembles the
production one
Keep any additional configuration in YAML files under the config/ directory
Rails::Application.config_for(:yaml_file)
Use nested routes to express better the relationship between ActiveRecord
models
nest routes more than 1 level deep then use the shallow: true option
namespaced routes to group related actions
Don't use match to define any routes unless there is need to map multiple request types among [:get, :post, :patch, :put, :delete] to a single action using :via option.
Keep the controllers skinny
all the business logic
should naturally reside in the model
Share no more than two instance variables between a controller and a view.
using a template
Prefer render plain: over render text
Prefer corresponding symbols to numeric HTTP status codes
without abbreviations
Keep your models for business logic and data-persistence
only
Group macro-style methods (has_many, validates, etc) in the beginning of
the class definition
Prefer has_many :through to has_and_belongs_to_many
self[:attribute]
self[:attribute] = value
validates
Keep custom validators under app/validators
Consider extracting custom validators to a shared gem
preferable to make a class method instead which serves the
same purpose of the named scope
returns an ActiveRecord::Relation
object
.update_attributes
Override the to_param method of the model
Use the friendly_id gem. It allows creation of human-readable URLs by
using some descriptive attribute of the model instead of its id
find_each to iterate over a collection of AR objects
.find_each
.find_each
Looping through a
collection of records from the database (using the all method, for example)
is very inefficient since it will try to instantiate all the objects at once
always call
before_destroy callbacks that perform validation with prepend: true
Define the dependent option to the has_many and has_one associations
always use the exception raising bang! method or handle the method return value.
When persisting AR objects
Avoid string interpolation in
queries
param will be properly escaped
Consider using named placeholders instead of positional placeholders
use of find over where
when you need to retrieve a single record by id
use of find_by over where and find_by_attribute
use of where.not over SQL
use
heredocs with squish
Keep the schema.rb (or structure.sql) under version control.
Use rake db:schema:load instead of rake db:migrate to initialize an empty
database
Enforce default values in the migrations themselves instead of in the
application layer
change_column_default
imposing data integrity from
the Rails app is impossible
use the change method instead of up and down methods.
constructive migrations
use models in migrations, make sure you define them
so that you don't end up with broken migrations in the future
Don't use non-reversible migration commands in the change method.
In this case, block will be used by create_table in rollback
Never call the model layer directly from a view
Never make complex formatting in the views, export the formatting to a method
in the view helper or the model.
When the labels of an ActiveRecord model need to be translated, use the
activerecord scope
Separate the texts used in the views from translations of ActiveRecord
attributes
Place the locale files for the models in a folder locales/models
the
texts used in the views in folder locales/views
Use the dot-separated keys in the controllers and models
Reserve app/assets for custom stylesheets, javascripts, or images
Third party code such as jQuery or
bootstrap should be placed in
vendor/assets
Provide both HTML and plain-text view templates
config.action_mailer.raise_delivery_errors = true
Use a local SMTP server like
Mailcatcher in the development
environment
Provide default settings for the host name
The _url methods include the host name and the _path
methods don't
_url
Format the from and to addresses properly
default from:
sending html emails all styles should be inline
Sending emails while generating page response should be avoided. It causes
delays in loading of the page and request can timeout if multiple email are
sent.
.start_with?
.end_with?
&.
Config your timezone accordingly in application.rb
config.active_record.default_timezone = :local
it can be only :utc or :local
Don't use Time.parse
Time.zone.parse
Don't use Time.now
Time.zone.now
Put gems used only for development or testing in the appropriate group in the
Gemfile
Add all OS X specific gems to a darwin group in the Gemfile, and
all Linux specific gems to a linux group
Do not remove the Gemfile.lock from version control.