Submitting a Pull Request¶
Proposed changes to Deis projects are made as GitHub pull requests.
Design Document¶
Before opening a pull request, ensure your change also references a design document if the contribution is substantial. For more information, see Design Documents.
Single Issue¶
It's hard to reach agreement on the merit of a PR when it isn't focused. When fixing an issue or implementing a new feature, resist the temptation to refactor nearby code or to fix that potential bug you noticed. Instead, open a separate issue or pull request. Keeping concerns separated allows pull requests to be tested, reviewed, and merged more quickly.
Squash and rebase the commit or commits in your pull request into logical units of work with git
. Include tests and documentation changes in the same commit, so that a revert would remove all traces of the feature or fix.
Most pull requests will reference a GitHub issue. In the PR description - not in the commit itself - include a line such as "closes #1234". The issue referenced will automatically be closed when your PR is merged.
Include Tests¶
If you significantly alter or add functionality to a component that impacts the broader Deis Workflow PaaS, you should submit a complementary PR to modify or amend end-to-end integration tests. These integration tests can be found in the deis/workflow-e2e repository.
See testing for more information.
Include Docs¶
Changes to any Deis Workflow component that could affect a user's experience also require a change or addition to the relevant documentation. For most Deis components, this involves updating the component's own documentation. In some cases where a component is tightly integrated into deis/workflow, its documentation must also be updated.
Cross-repo commits¶
If a pull request is part of a larger piece of work involving one or more additional commits in other Workflow repositories, these commits can be referenced in the last PR to be submitted. The downstream e2e test job will then supply every referenced commit (derived from PR issue number supplied) to the test runner so it can source the necessary Docker images for inclusion in the generated Workflow chart to be tested.
For example, consider paired commits in deis/controller and deis/workflow-e2e. The commit body for the first PR in deis/workflow-e2e
would look like:
feat(foo_test): add e2e test for feature foo
[skip e2e] test for controller#42
Adding [skip e2e]
forgoes the e2e tests on this commit. This and any other required PRs aside from the final PR should be submitted first, so that their respective build and image push jobs run.
Lastly, the final PR in deis/controller
should be created with the required PR number(s) listed, in the form of [Rr]equires <repoName>#<pullRequestNumber>
, for use by the downstream e2e run.
feat(foo): add feature foo
Requires workflow-e2e#42
Code Standards¶
Deis components are implemented in Go and Python. For both languages, we agree with The Zen of Python, which emphasizes simple over clever. Readability counts.
Go code should always be run through gofmt
on the default settings. Lines of code may be up to 99 characters long. Documentation strings and tests are required for all exported functions. Use of third-party go packages should be minimal, but when doing so, such dependencies should be managed via the glide tool.
Python code should always adhere to PEP8, the python code style guide, with the exception that lines of code may be up to 99 characters long. Docstrings and tests are required for all public methods, although the flake8 tool used by Deis does not enforce this.
Commit Style¶
We follow a convention for commit messages borrowed from CoreOS, who borrowed theirs from AngularJS. This is an example of a commit:
feat(scripts/test-cluster): add a cluster test command
this uses tmux to setup a test cluster that you can easily kill and
start for debugging.
To make it more formal, it looks something like this:
{type}({scope}): {subject}
<BLANK LINE>
{body}
<BLANK LINE>
{footer}
The allowed {types}
are as follows:
feat
-> featurefix
-> bug fixdocs
-> documentationstyle
-> formattingref
-> refactoring codetest
-> adding missing testschore
-> maintenance
The {scope}
can be anything specifying the location(s) of the commit change(s).
The {subject}
needs to be an imperative, present tense verb: “change”, not “changed” nor
“changes”. The first letter should not be capitalized, and there is no dot (.) at the end.
Just like the {subject}
, the message {body}
needs to be in the present tense, and includes
the motivation for the change, as well as a contrast with the previous behavior. The first
letter in a paragraph must be capitalized.
All breaking changes need to be mentioned in the {footer}
with the description of the
change, the justification behind the change and any migration notes required.
Any line of the commit message cannot be longer than 72 characters, with the subject line limited to 50 characters. This allows the message to be easier to read on GitHub as well as in various git tools.
Merge Approval¶
Any code change - other than a simple typo fix or one-line documentation change - requires at least two Deis maintainers to accept it. Maintainers tag pull requests with "LGTM1" and "LGTM2" (Looks Good To Me) labels to indicate acceptance.
No pull requests can be merged until at least one core maintainer signs off with an LGTM. The other LGTM can come from either a core maintainer or contributing maintainer.
If the PR is from a Deis maintainer, then he or she should be the one to close it. This keeps the commit stream clean and gives the maintainer the benefit of revisiting the PR before deciding whether or not to merge the changes.
An exception to this is when an errant commit needs to be reverted urgently. If necessary, a PR that only reverts a previous commit can be merged without waiting for LGTM approval.


|
|
About the Jepson Herbarium
|
Willis Linn Jepson
(1867–1946), in the Sierra Nevada, 1911. California's most eminent early botanist and founder of the Jepson Herbarium (1950). |
The mission of the Jepson Herbarium
is to understand and conserve the California flora through systematic, floristic, and conservation biology studies and to communicate knowledge of the flora through publications and instructional programs. The goals and programs of the Jepson Herbarium
are based on three directives put forth by our founder, Willis Linn Jepson:
• Update the Manual of the Flowering Plants of California (1925)
• Complete A Flora of California with color illustrations
• Maintain and expand the botanical collection and library
Data from current and past floristic studies of the Jepson Herbarium are available through the Jepson Online Interchange for California Floristics; this resource provides the latest information on identification, taxonomy, nomenclature, distribution, ecology, relationships, and diversity of California vascular plants. Large databases of specimen label and horticultural information are also available. Willis Jepson’s field books are available online.
In addition to overseeing the Jepson Flora Project, the Jepson Curator maintains an active research program. He and his graduate students employ biosystematic, morphological, and molecular techniques to answer questions related to phylogeny, ecology, and evolution of plants.
In addition to research and floristic studies, the Herbarium provides educational opportunities for interested amateur and professional botanists through the weekend workshop series.
Through all of the programs of the Herbarium, we strive to be a liaison between the scientific community and the interested public and support conservation efforts around the state.
|
|
|


Bhargav Visani
I Love
creating
designing
developing
Enter your text
Change text
Demo Text This text replace after
put some value in TEXT BOX and hit Change text button


This repo is part of my growing portfolio of projects as I continue learning the ins and outs of Object Oriented Programming.
This project is written in JavaScript. This project was derived from Udemy instructions from the JavaScript Game Development Step by Step course. This project showcases how to load image assets in the game instead of drawing objects. Along with setting different intervals inside the game.
Just about any web browser will support this small game example.
go to this link to view this project live :
This project is licensed under the MIT License


{% extends "base.html" %} {% block title %}Activation Complete | MROCP {% endblock %} {% block content %}
Thanks for joining the scientific journey. You may now access https secured portions of the site.
Click here to create private projects. Remember to ensure you only enter your password on https url enabled pages.
{% endblock %}


We've all looked at the mess we've just made and then have chosen to leave it for another day.
We've all felt the relief of seeing our messy program work and deciding that a working mess is better than nothing.
We've all said we'd go back and clean it up later.
Of course, in those days we didn't know LeBlanc's law: Later equals never.
我们都曾经瞟一眼刚刚写的糟糕的代码，并决定改天再修改它。我们都曾感到轻松：看到糟糕的代码能运行，并认为一个能运行的糟糕代码胜过什么都没有。我们都曾说过等以后再返回来修改这些糟糕代码。当然，在那些日子里，我们没有听说过勒布朗（LeBlanc）法则：稍后等于永不（Later equals never）。


Cargo
Chief Quick Quote: 201,102; October 15, 2011, 14:23
For: ABC Strawberry Growers,<PHONE_NUMBER><EMAIL_ADDRESS>What: Safeway PO SW234-098, 20 Pallets, Length 48 Width 40 Height 48 inches, Not
Stackable, Total weigh 20,000 #, Class
50
Origin:
Gilroy, CA, 95020, Biz w/ Dock or Forklift
Destination:
Menasha, WI, 54952, Biz w/ Dock or Forklift; ~2,238
Miles
Bid
Summary
Number
of Bids: 45 Lowest Bid: $1,534
Highest Bid: $3,204 Average Bid: $2,369
Best Bids:
Estimated
Location
Trucking Firm Rating Duration Tracking Price Choose
Smith & Brown ¶ ¶ ¶ ¶ (24) 3
Days ü $2,650 Book Load
ABC Trucking
¶
¶
¶
¶ ¶ (15) 3 Days/Guaranteed ü $3,070 Book Load
Blue Transport
¶
¶ ¶ (57) 3 Days $1,534 Book Load
Best Trucking
¶
¶
¶
¶ ¶ (92) 2 Days/Guaranteed ü $3,204 Book Load
Jason Trucking
¶
¶
¶
(150) 3 Days $1,670 Book Load


Really Simple Dispersion (Wasm)
Interactive atmospheric dispersion model simulation for industrial plant emissions, over 1-100 hours of operation.
Plan view (top) - ground level emissions over a 5km x 5km area. Side elevation (bottom) - average emissions up to 1km altitude. Shown on
a contoured log scale.
Written in Rust and compiled to WebAssembly (Wasm), more information and source code at:
https://github.com/joshuanunn/really-simple-dispersion-wasm


This is to test SVG graphics. The following image is SVG, if it displays, the test passes.
This is to test SVG graphics. The following image is rendered in SVG, if it displays, the test passes.


We're so excited to finally
07.02.16
"The best love is the kind that awakens the soul; that makes us reach for more, that plants the fire in our hearts and brings peace to our minds. That’s what I hope to give you forever."
— The Notebook
We are so lucky to have all of you in our lives, your love and support mean the world to us over the years. Now let's celebrate with food, family, friends and of course dancing!
Ceremony starts at 6:30 followed by dinner.
Limited beer & wine so BYOB


| Property | Value |
| Project Name: | c:\5248021\ce2704_hw10 |
| Target Device: | xc2s200 |
| Report Generated: | Friday 02/24/12 at 18:07 |
| Printable Summary (View as HTML) | piggy_summary.html |
| Logic Utilization | Used | Available | Utilization | Note(s) |
| Data Not Yet Available |
| Property | Value |
| Data Not Yet Available |
| Constraint(s) | Requested | Actual | Logic Levels |
| Data Not Yet Available |
| Report Name | Status | Last Date Modified |


GraphMaker
Make your own graph in 3 simple steps!
Home
Step 1:
Choose the type of graph/chart:
Bar Graph
Pie Chart
Line Graph


HyberPushNotification
public struct HyberPushNotification
Apple Remote Push-notification presenter
See also
The Remote Notification Payload-
UInt64
Hyber message identifierDeclaration
Swift
public let hyberMessageID: UInt64
-
String
Google Cloud Messaging message identifierDeclaration
Swift
public let gcmMessageID: String?
-
String
representing sender. Can benil
Declaration
Swift
public let sender: String
-
The number to display as the app’s icon badge.
Declaration
Swift
public let bage: Int?
-
The name of the file containing the sound to play when an alert is displayed.
Declaration
Swift
public let sound: String?
-
Provide this key with a value of
true
to indicate that new content is available. Including this key and value means that when your app is launched in the background or resumedapplication:didReceiveRemoteNotification:fetchCompletionHandler:
is called.Declaration
Swift
public let contentAvailable: Bool
-
Provide this key with a string value that represents the identifier property of the
UIMutableUserNotificationCategory
object you created to define custom actions. To learn more about using custom actions.Declaration
Swift
public let category: String?
-
The text of the alert message.
Declaration
Swift
public let body: String?
-
A short string describing the purpose of the notification. Apple Watch displays this string as part of the notification interface. This string is displayed only briefly and should be crafted so that it can be understood quickly. This key was added in iOS 8.2.
Declaration
Swift
public let title: String?
-
The key to a title string in the
Localizable.strings
file for the current localization. The key string can be formatted with%@
and%n$@
specifiers to take the variables specified in thetitleLocalizationArguments
array.Declaration
Swift
public let titleLocalizationKey: String?
-
Variable string values to appear in place of the format specifiers in
titleLocalizationKey
.Declaration
Swift
public let titleLocalizationArguments: [String]?
-
If a string is specified, the system displays an alert that includes the Close and View buttons. The string is used as a key to get a localized string in the current localization to use for the right button’s title instead of “View”.
Declaration
Swift
public let actionLocalizationKey: String?
-
A key to an alert-message string in a
Localizable.strings
file for the current localization (which is set by the user’s language preference). The key string can be formatted with%@
and%n$@
specifiers to take the variables specified in thelocalizationArguments
array.Declaration
Swift
public let localizationKey: String?
-
Variable string values to appear in place of the format specifiers in
localizationKey
Declaration
Swift
public let localizationArguments: [String]?
-
The filename of an image file in the app bundle; it may include the extension or omit it. The image is used as the launch image when users tap the action button or move the action slider. If this property is not specified, the system either uses the previous snapshot,uses the image identified by the
UILaunchImageFile
key in the app’sInfo.plist
file, or falls back toDefault.png
.Declaration
Swift
public let launchImage: String?
-
Bool
that indicates user allowed alert- or sound-notifications for this application is SettingsDeclaration
Swift
public let notificationsAllowed: Bool
-
Push-notification’s delivered
NSDate
Declaration
Swift
public let deliveredDate: NSDate
-
Returns
UILocalNotification
initialized withself
- Returns: NewUILocalNotification
objectDeclaration
Swift
public func localNotification() -> UILocalNotification
Return Value
New
UILocalNotification
object


You create a seismic disturbance at a point on the ground that you can see within range. For the duration, an intense tremor rips through the ground in a 100-foot-radius circle centered on that point and shakes creatures and structures in contact with the ground in that area.
The ground in the area becomes difficult terrain.
Each creature on the ground that is concentrating must make a Constitution saving throw. On a failed save, the creature's concentration is broken.
When you cast this spell and at the end of each turn you spend concentrating on it, each creature on the ground in the area must make a Dexterity saving throw.
On a failed save, the creature is knocked prone.
This spell can have additional effects depending on the terrain in the area, as determined by the DM.
Fissures. Fissures open throughout the spell's area at the start of your next turn after you cast the spell. A total of 1d6 such fissures open in locations chosen by the DM.
Each is 1d10 x 10 feet deep, 10 feet wide, and extends from one edge of the spell's area to the opposite side.
 A creature that successfully saves moves with the fissure's edge as it opens.
A fissure that opens beneath a structure causes it to automatically collapse (see below).
Structures. The tremor deals 50 bludgeoning damage to any structure in contact with the ground in the area when you cast the spell and at the start of each of your turns until the spell ends. If a structure drops to 0 hit points, it collapses and potentially damages nearby creatures. A creature within half the distance of a structure's height must make a Dexterity saving throw.
On a failed save, the creature takes 5d6 bludgeoning damage, is knocked prone, and is buried in the rubble, requiring a DC 20 Strength (Athletics) check as an action to escape. The DM can adjust the DC higher or lower, depending on the nature of the rubble. On a successful save, the creature takes half as much damage and doesn't fall prone or become buried.


--- title: Metrics keywords: fastai sidebar: home_sidebar nb_path: "nbs/07_metrics.ipynb" ---
pred = torch.tensor([[ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[ 0, 0, 0, 0, 0, 1, 0, 1, 0, 0],
[ 1, 1, 1, 1, 1, 0, 1, 0, 0, 1]]).t()
targ = torch.tensor([[-1,-1,-1,-1,-1, 1, 2, 1, 0, 0]])
acc = MaskedAccuracy(-1)
assert acc.func(pred[None], targ) == 0.8
class BPC(AvgLoss):
"Bit per character for Language Models"
@property
def value(self): return self.total/self.count/math.log(2) if self.count != 0 else None
@property
def name(self): return "bpc"
bpc = BPC()
Bits-Per-Character was used as a metric for the language modelling tasks, where a character-level tokenizer was used. Calculated as CrossEntropy/log(2)


 So has an attacker stolen any funds from wallets?
[telegram] <GLCNI01> Guys is the server for non versus agama wallet expected to be back up, I can't access my wallet to move to a new one
The seed phrese generates a different public address on the verus version
[telegram] <cmyslopez> We are close to top 45 in CMC
(edited)
[telegram] <icantgiveyou> Yes my funds are gone
[telegram] <icantgiveyou>
[telegram] <yanomi> Looking at my wallet i see my funds have been sent to two different addresses on the 5th June. Can any Admins confirm if this right?
[telegram] <icantgiveyou> Same on 1 address
[telegram] <Sergio> komodo trying to pump
[telegram] <yanomi> have you filled in the form to claim back? (re @icantgiveyou: Yes my funds are gone)


| Interface | Description |
|---|---|
| CloverPost | |
| CloverWorkerListener |
This interface describes a listener which listens to a CloverWorker and thus
can react on worker finishing, either gracefully or abnormally
|
| FutureOfCallable<C extends java.util.concurrent.Callable<R>,R> |
This class is extension of regular
Future class. |
| FutureOfRunnable<T extends java.lang.Runnable> |
This class is extension of regular
Future class. |
| IThreadManager | |
| WatchDogFuture |
WatchDogFuture class is a
Future of a running WatchDog . |
| Class | Description |
|---|---|
| AuthorityProxyDescription |
Description for AuthorityProxy extension point.
|
| AuthorityProxyFactory |
Factory for authority proxy extension point.
|
| CloverClassPath |
This class is only simple container for two list of classpath URLs.
1) Runtime classpath URLs should be used as an extra list of places where to search classes given direct in graph.
2) Compile classpath URLs should be used as an extra list of libraries which should be part of -classpath
in compile time for java source given direct in graph.
|
| CloverWorker |
This implementation of Runnable interface should be use for each thread inside a
component.
|
| CloverWorkerListener.Event |
An event class carries all information needed when an CloverWorker talks to its listeners
|
| EngineInitializer |
Clover.ETL engine initializer.
|
| ErrorMsgBody | |
| GraphRuntimeContext |
Common used implementation of IGraphRuntimeContext interface.
|
| GraphTrackingLogger |
Console logger of all tracking information.
|
| IAuthorityProxy | |
| IAuthorityProxy.FileOperationResult | |
| IAuthorityProxy.RemoteEdgeDataSource |
This class represents data source of a remote edge -
pair of input stream and runId of remote job.
|
| IAuthorityProxy.RemoteEdgeDataTarget |
This class represents data target of a remote edge -
pair of output stream and runId of remote job.
|
| IAuthorityProxy.RunStatus | |
| JobflowTrackingLogger |
Console logger of all tracking information.
|
| Message<T> | |
| PrimitiveAuthorityProxy | |
| SimpleThreadManager | |
| SingleThreadWatchDog |
Alternative implementation of
WatchDog . |
| TempSpace |
TempSpace is a directory where temp files are stored.
|
| TrackingLogger |
Console logger of all tracking information.
|
| WatchDog |
Description of the Class
|
| Enum | Description |
|---|---|
| ExecutionType |
Clover engine supports two possible execution types.
|
| GraphRuntimeContext.PropertyKey |
This enum is attempt to provide a more generic way to this runtime configuration.
|
| IAuthorityProxy.FileOperationResult.ProblemType | |
| Message.Type |
Copyright © 2002-2015 Javlin a.s.


A student under PostGraduate. My research-direction is indoor SLAM with laser and visual sensors.
---
layout: endefault
permalink: /en
title: Bob Liao's Blog
---
A student under PostGraduate. My research-direction is indoor SLAM with laser and visual sensors.
Blogs | Browse by Tags
| {{ post.date | date: "%Y-%m-%d" }} | {{ post.title }} |
| There haven't been any English blogs yet. |
All posts archived


The Negroni is a popular Italian cocktail, made of one part gin, one part vermouth rosso (red, semi-sweet), and one part Campari, garnished with orange peel.It is considered an apéritif.
While the drink's origins are unknown, the most widely reported account is that it was first mixed in Florence, Italy, in 1919, at Caffè Casoni (formerly Caffè Giacosa), located on Via de' Tornabuoni and now called Caffè Roberto Cavalli. Count Camillo Negroni concocted it by asking the bartender, Fosco Scarselli, to strengthen his favorite cocktail, the Americano, by adding gin rather than the normal soda water. The bartender also added an orange garnish rather than the typical lemon garnish of the Americano to signify that it was a different drink.


[gecode-users] order of "wait" statements maintained?
Martin Mann
mmann at informatik.uni-freiburg.de
Tue Apr 30 10:26:41 CEST 2013
Another question arised when posting this
branch(*this, A, ..);
branch( *this, &checkA );
branch(*this, B, ..);
wait( *this, A+B, &checkB );
I thought about replacing the wait with another branch call. But are
branchers always called even if all variables are assigned?
Or is the given solution better than the "4-branch-option"?
And where is the true difference also for performance etc.? Guess the
wait call does more checks on the domains?!?
Thanks,
Martin
Am 30.04.2013 09:58, schrieb Martin Mann:
>
> Hi Christian,
>
> guessed as much.. mhh.. think the additional bool var wont be a problem
> but I will give the branch call with &checkA a first try, since it keeps
> the CSP small without further variables etc.
>
> Thanks for you help,
> Martin
>
>
> Am 29.04.2013 20:06, schrieb Christian Schulte:
>> Hi Martin,
>>
>> There is no order among several waits. You could either use branch with a
>> function as you suggested (calling status is in fact fine) or you could
>> encode the order yourself. Make checkA and checkB assign a variable
>> and then
>> you wait on these variables as well. Would that do?
>>
>> Cheers
>> Christian
>>
>> --
>> Christian Schulte, www.ict.kth.se/~cschulte/
>>
>>
>>> -----Original Message-----
>>> From: users-bounces at gecode.org [mailto:users-bounces at gecode.org] On
>>> Behalf Of Martin Mann
>>> Sent: Monday, April 29, 2013 5:39 PM
>>> To: gecode user list
>>> Subject: [gecode-users] order of "wait" statements maintained?
>>>
>>>
>>> Hi everybody,
>>>
>>> for some processing, I post something like this in my Space constructor
>>>
>>> wait( *this, A, &checkA);
>>> wait( *this, B, &checkB);
>>> wait( *this, A+B, &printAB);
>>>
>>> branch( *this, A, .. );
>>> branch( *this, B, .. );
>>>
>>> to do some dedicated successive checks on assignments of A, B and both A
>> and
>>> B.
>>>
>>> Since my last printAB depends on the outcome of both checkA and checkB
>> (both
>>> might make the CSP fail) I need to know if the processing order of the
>> wait
>>> statements the same as their posting order within the constructor... :/
>>>
>>> Or is there a better solution to that as posting an according branching
>> like
>>>
>>> branch( *this, &checkA );
>>>
>>> where I first have to trigger constraint propagation in order to ensure
>>> assignment... !??!
>>>
>>> Thanks for your help,
>>> Martin
>>>
>>>
--
Dr. Martin Mann, Postdoc
Bioinformatics - Inst. of Computer Science
Albert-Ludwigs-University Freiburg
Tel: ++49-761-203-8254
Fax: ++49-761-203-7462
http://www.bioinf.uni-freiburg.de/~mmann/
More information about the users
mailing list


Toggle navigation
DSC
About
Education
Coding Playground
Achievements
Gallery
Contact
FREE TUTION AVAILABLE
Write your details below
NAME
EMAIL ADDRESS:(college id only)
CONTACT NO.
WHICH YEAR
GENDER
MALE
FEMALE
SUBJECT NAMES
(you can select more than one option)
1.DEEP LEARNING
2.PYTHON AND DATA SCIENCE
3.DATA STRUCTURE
4.ALGORITHM-I
Previous Experience on any subject
(if any)
Submit
Reset
Contact Info:
Mobile No -
+917595932084
Email-id -
<EMAIL_ADDRESS>Address -
A-10/137, IIIT Kalyani Boys Hostel, Kalyani, Nadia, W.B.- 741235
Follow me on:


DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON https://guides.rubyonrails.org.
Using Rails for API-only Applications
In this guide you will learn:
- What Rails provides for API-only applications
- How to configure
Rails
to start without any browser features - How to decide which middleware you will want to include
- How to decide which modules to use in your controller
What is an API Application?
Traditionally, when people said that they used Rails
as an "API", they meant
providing a programmatically accessible API alongside their web application.
For example, GitHub provides an API that you
can use from your own custom clients.
With the advent of client-side frameworks, more developers are using Rails
to
build a back-end that is shared between their web application and other native
applications.
For example, Twitter uses its public API in its web application, which is built as a static site that consumes JSON resources.
Instead of using Rails
to generate HTML that communicates with the server
through forms and links, many developers are treating their web application as
just an API client delivered as HTML with JavaScript that consumes a JSON API.
This guide covers building a Rails
application that serves JSON resources to an
API client, including client-side frameworks.
Why Use Rails
for JSON APIs?
The first question a lot of people have when thinking about building a JSON API
using Rails
is: "isn't using Rails
to spit out some JSON overkill? Shouldn't I
just use something like Sinatra?".
For very simple APIs, this may be true. However, even in very HTML-heavy applications, most of an application's logic lives outside of the view layer.
The reason most people use Rails
is that it provides a set of defaults that
allows developers to get up and running quickly, without having to make a lot of trivial
decisions.
Let's take a look at some of the things that Rails
provides out of the box that are
still applicable to API applications.
Handled at the middleware layer:
- Reloading:
Rails
applications support transparent reloading. This works even if your application gets big and restarting the server for every request becomes non-viable. - Development Mode:
Rails
applications come with smart defaults for development, making development pleasant without compromising production-time performance. - Test Mode: Ditto development mode.
- Logging:
Rails
applications log every request, with a level of verbosity appropriate for the current mode. Rails logs in development include information about the request environment, database queries, and basic performance information. - Security:
Rails
detects and thwarts IP spoofing attacks and handles cryptographic signatures in a timing attack aware way. Don't know what an IP spoofing attack or a timing attack is? Exactly. - Parameter Parsing: Want to specify your parameters as JSON instead of as a
URL-encoded String? No problem. Rails will decode the JSON for you and make
it available in
params
. Want to use nested URL-encoded parameters? That works too. - Conditional GETs:
Rails
handles conditionalGET
(ETag
andLast-Modified
) processing request headers and returning the correct response headers and status code. All you need to do is use thestale?
check in your controller, and Rails will handle all of the HTTP details for you. - HEAD requests:
Rails
will transparently convertHEAD
requests intoGET
ones, and return just the headers on the way out. This makesHEAD
work reliably in all Rails APIs.
While you could obviously build these up in terms of existing Rack
middleware,
this list demonstrates that the default Rails
middleware stack provides a lot
of value, even if you're "just generating JSON".
Handled at the Action Pack layer:
- Resourceful Routing: If you're building a RESTful JSON API, you want to be using the Rails router. Clean and conventional mapping from HTTP to controllers means not having to spend time thinking about how to model your API in terms of HTTP.
- URL Generation: The flip side of routing is URL generation. A good API based on HTTP includes URLs (see the GitHub Gist API for an example).
- Header and Redirection Responses:
head :no_content
andredirect_to user_url(current_user)
come in handy. Sure, you could manually add the response headers, but why? - Caching:
Rails
provides page, action, and fragment caching. Fragment caching is especially helpful when building up a nested JSON object. - Basic,
Digest
, and Token Authentication:Rails
comes with out-of-the-box support for three kinds of HTTP authentication. - Instrumentation:
Rails
has an instrumentation API that triggers registered handlers for a variety of events, such as action processing, sending a file or data, redirection, and database queries. The payload of each event comes with relevant information (for the action processing event, the payload includes the controller, action, parameters, request format, request method, and the request's full path). - Generators: It is often handy to generate a resource and get your model, controller, test stubs, and routes created for you in a single command for further tweaking. Same for migrations and others.
- Plugins: Many third-party libraries come with support for
Rails
that reduce or eliminate the cost of setting up and gluing together the library and the web framework. This includes things like overriding default generators, adding Rake tasks, and honoring Rails choices (like the logger and cache back-end).
Of course, the Rails
boot process also glues together all registered components.
For example, the Rails
boot process is what uses your config/database.yml
file
when configuring Active Record.
The short version is: you may not have thought about which parts of Rails
are still applicable even if you remove the view layer, but the answer turns out
to be most of it.
The Basic Configuration
If you're building a Rails
application that will be an API server first and
foremost, you can start with a more limited subset of Rails
and add in features
as needed.
Creating a New Application
You can generate a new api Rails
app:
$ rails new my_api --api
This will do three main things for you:
- Configure your application to start with a more limited set of middleware than normal. Specifically, it will not include any middleware primarily useful for browser applications (like cookies support) by default.
- Make
ApplicationController
inherit from::ActionController::API
instead of::ActionController::Base
. As with middleware, this will leave out any Action Controller modules that provide functionalities primarily used by browser applications. - Configure the generators to skip generating views, helpers, and assets when you generate a new resource.
Changing an Existing Application
If you want to take an existing application and make it an API one, read the following steps.
In config/application.rb
, add the following line at the top of the Application
class definition:
config.api_only = true
In config/environments/development.rb
, set config.debug_exception_response_format
to configure the format used in responses when errors occur in development mode.
To render an HTML page with debugging information, use the value :default
.
config.debug_exception_response_format = :default
To render debugging information preserving the response format, use the value :api
.
config.debug_exception_response_format = :api
By default, config.debug_exception_response_format
is set to :api
, when config.api_only
is set to true.
Finally, inside app/controllers/application_controller.rb
, instead of:
class ApplicationController < ActionController::Base
end
do:
class ApplicationController < ActionController::API
end
Choosing Middleware
An API application comes with the following middleware by default:
::ActionDispatch::HostAuthorization
Rack::Sendfile
::ActionDispatch::Static
::ActionDispatch::Executor
::ActiveSupport::Cache::Strategy::LocalCache::Middleware
Rack::Runtime
::ActionDispatch::RequestId
::ActionDispatch::RemoteIp
::Rails::Rack::Logger
::ActionDispatch::ShowExceptions
::ActionDispatch::DebugExceptions
::ActionDispatch::ActionableExceptions
::ActionDispatch::Reloader
::ActionDispatch::Callbacks
::ActiveRecord::Migration::CheckPending
Rack::Head
Rack::ConditionalGet
Rack::ETag
See the internal middleware section of the Rack guide for further information on them.
Other plugins, including Active Record, may add additional middleware. In general, these middleware are agnostic to the type of application you are building, and make sense in an API-only Rails application.
You can get a list of all middleware in your application via:
$ bin/rails middleware
Using the Cache Middleware
By default, Rails will add a middleware that provides a cache store based on the configuration of your application (memcache by default). This means that the built-in HTTP cache will rely on it.
For instance, using the stale?
method:
def show
@post = Post.find(params[:id])
if stale?(last_modified: @post.updated_at)
render json: @post
end
end
The call to stale?
will compare the If-Modified-Since
header in the request
with @post.updated_at
. If the header is newer than the last modified, this
action will return a "304 Not Modified" response. Otherwise, it will render the
response and include a Last-Modified
header in it.
Normally, this mechanism is used on a per-client basis. The cache middleware
allows us to share this caching mechanism across clients. We can enable
cross-client caching in the call to stale?
:
def show
@post = Post.find(params[:id])
if stale?(last_modified: @post.updated_at, public: true)
render json: @post
end
end
This means that the cache middleware will store off the Last-Modified
value
for a URL in the Rails cache, and add an If-Modified-Since
header to any
subsequent inbound requests for the same URL.
Think of it as page caching using HTTP semantics.
Using Rack::Sendfile
When you use the send_file
method inside a Rails controller, it sets the
X-Sendfile
header. Rack::Sendfile
is responsible for actually sending the
file.
If your front-end server supports accelerated file sending, Rack::Sendfile
will offload the actual file sending work to the front-end server.
You can configure the name of the header that your front-end server uses for
this purpose using config.action_dispatch.x_sendfile_header
in the appropriate
environment's configuration file.
You can learn more about how to use Rack::Sendfile
with popular
front-ends in the Rack::Sendfile
documentation.
Here are some values for this header for some popular servers, once these servers are configured to support accelerated file sending:
# Apache and lighttpd
config.action_dispatch.x_sendfile_header = "X-Sendfile"
# Nginx
config.action_dispatch.x_sendfile_header = "X-Accel-Redirect"
Make sure to configure your server to support these options following the
instructions in the Rack::Sendfile
documentation.
Using ActionDispatch::Request
ActionDispatch::Request#params
will take parameters from the client in the JSON
format and make them available in your controller inside params
.
To use this, your client will need to make a request with JSON-encoded parameters
and specify the Content-Type
as application/json
.
Here's an example in jQuery:
jQuery.ajax({
type: 'POST',
url: '/people',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify({ person: { firstName: "Yehuda", lastName: "Katz" } }),
success: function(json) { }
});
::ActionDispatch::Request
will see the Content-Type
and your parameters
will be:
{ :person => { :firstName => "Yehuda", :lastName => "Katz" } }
Using Session Middlewares
The following middlewares, used for session management, are excluded from API apps since they normally don't need sessions. If one of your API clients is a browser, you might want to add one of these back in:
::ActionDispatch::Session::CacheStore
::ActionDispatch::Session::CookieStore
::ActionDispatch::Session::MemCacheStore
The trick to adding these back in is that, by default, they are passed session_options
when added (including the session key), so you can't just add a session_store.rb
initializer, add
use ActionDispatch::Session::CookieStore
and have sessions functioning as usual. (To be clear: sessions
may work, but your session options will be ignored - i.e. the session key will default to _session_id
)
Instead of the initializer, you'll have to set the relevant options somewhere before your middleware is
built (like config/application.rb
) and pass them to your preferred middleware, like this:
# This also configures session_options for use below
config.session_store :, key: '_interslice_session'
# Required for all session management (regardless of session_store)
config.middleware.use ActionDispatch::Cookies
config.middleware.use config.session_store, config.
Other Middleware
Rails ships with a number of other middleware that you might want to use in an API application, especially if one of your API clients is the browser:
Rack::MethodOverride
::ActionDispatch::Cookies
::ActionDispatch::Flash
Any of these middleware can be added via:
config.middleware.use Rack::MethodOverride
Removing Middleware
If you don't want to use a middleware that is included by default in the API-only middleware set, you can remove it with:
config.middleware.delete ::Rack::Sendfile
Keep in mind that removing these middlewares will remove support for certain features in Action Controller.
Choosing Controller Modules
An API application (using ::ActionController::API
) comes with the following
controller modules by default:
::ActionController::UrlFor
: Makesurl_for
and similar helpers available.::ActionController::Redirecting
: Support forredirect_to
.::AbstractController::Rendering
and::ActionController::ApiRendering
: Basic support for rendering.::ActionController::Renderers::All
: Support forrender :json
and friends.::ActionController::ConditionalGet
: Support forstale?
.::ActionController::BasicImplicitRender
: Makes sure to return an empty response, if there isn't an explicit one.::ActionController::StrongParameters
: Support for parameters filtering in combination with Active Model mass assignment.::ActionController::DataStreaming
: Support forsend_file
andsend_data
.::AbstractController::Callbacks
: Support forbefore_action
and similar helpers.::ActionController::Rescue
: Support forrescue_from
.::ActionController::Instrumentation
: Support for the instrumentation hooks defined by Action Controller (see the instrumentation guide for more information regarding this).::ActionController::ParamsWrapper
: Wraps the parameters hash into a nested hash, so that you don't have to specify root elements sending POST requests for instance.::ActionController::Head
: Support for returning a response with no content, only headers.
Other plugins may add additional modules. You can get a list of all modules
included into ::ActionController::API
in the rails console:
irb> ActionController::API.ancestors - ActionController::Metal.ancestors
=> [ActionController::API,
ActiveRecord::Railties::ControllerRuntime,
ActionDispatch::Routing::RouteSet::MountedHelpers,
ActionController::ParamsWrapper,
... ,
AbstractController::Rendering,
ActionView::ViewPaths]
Adding Other Modules
All Action Controller modules know about their dependent modules, so you can feel free to include any modules into your controllers, and all dependencies will be included and set up as well.
Some common modules you might want to add:
::AbstractController::Translation
: Support for thel
andt
localization and translation methods.- Support for basic, digest, or token HTTP authentication:
::ActionView::Layouts
: Support for layouts when rendering.::ActionController::MimeResponds
: Support forrespond_to
.::ActionController::Cookies
: Support forcookies
, which includes support for signed and encrypted cookies. This requires the cookies middleware.::ActionController::Caching
: Support view caching for the API controller. Please note that you will need to manually specify the cache store inside the controller like this:class ApplicationController < ActionController::API include ::ActionController::Caching self.cache_store = :mem_cache_store end
Rails does not pass this configuration automatically.
The best place to add a module is in your ApplicationController
, but you can
also add modules to individual controllers.