Skip to content

Latest commit

 

History

History
291 lines (212 loc) · 6.51 KB

README.md

File metadata and controls

291 lines (212 loc) · 6.51 KB

Fauna

Ruby client for the Fauna API.

Installation

The Fauna ruby client is distributed as a gem. Install it via:

$ gem install fauna

Or if you use Bundler, add it to your application's Gemfile:

gem 'fauna'

And then execute:

$ bundle

Compatibility

Tested and compatible with MRI 1.9.3. Other Rubies may also work.

Basic Usage

First, require the gem:

require "rubygems"
require "fauna"

Configuring the API

All API requests start with an instance of Fauna::Connection.

Creating a connection requires either a token, a publisher key, a client key, or the publisher's email and password.

Let's use the email and password to get a publisher key:

root = Fauna::Connection.new(email: "publisher@example.com", password: "secret")
publisher_key = root.post("keys/publisher")['resource']['key']

Now we can make a global publisher-level connection:

$fauna = Fauna::Connection.new(publisher_key: publisher_key)

You can optionally configure a logger on the connection to ease debugging:

require "logger"
$fauna = Fauna::Connection.new(
  publisher_key: publisher_key,
  logger: Logger.new(STDERR))

Client Contexts

The easiest way to work with a connection is to open up a client context, and then manipulate resources within that context:

Fauna::Client.context($fauna) do
  user = Fauna::User.create!(email: "taran@example.com")
  user.data["name"] = "Taran"
  user.data["profession"] = "Pigkeeper"
  user.save!
  user.destroy
end

By working within a context, not only are you able to use a more convienient, object-oriented API, you also gain the advantage of in-process caching.

Within a context block, requests for a resource that has already been loaded via a previous request will be returned from the cache and no query will be issued. This substantially lowers network overhead, since Fauna makes an effort to return related resources as part of every response.

Fauna::Resource

All instances of fauna classes have built-in accessors for common fields:

Fauna::Client.context($fauna) do
  user = Fauna::User.create(unique_id: "taran77")

  # fields
  user.ref       # => "users/123"
  user.ts        # => 2013-01-30 13:02:46 -0800
  user.deleted   # => false
  user.unique_id # => "taran77"

  # data and references
  user.data       # => {}
  user.references # => {}

  # changes event set
  user.changes
end

Rails Usage

Fauna provides ActiveModel-compatible classes that can be used directly in Rails.

Fauna also provides a Rails helper that sets up a default context in controllers, based on credentials in config/fauna.yml:

development:
  email: taran@example.com
  password: secret
  publisher_key: secret_key
test:
  email: taran@example.com
  password: secret

(In config/fauna.yml, if an existing publisher key is specified, the email and password can be omitted. If a publisher key is not specified, a new one will be created each time the app is started.)

Then, in config/initializers/fauna.rb:

require "fauna/rails"

Fauna.schema do
  # See below for schema setup
end

Setting Up the Schema

First, create some Ruby classes to model your domain. They must inherit from the Fauna::Class base class:

# Create a custom Pig class.
class Pig < Fauna::Class
    # Fields can be configured dynamically
    field :name, :title
end

# Create a custom Vision class
class Vision < Fauna::Class
  field :pronouncement
  reference :pig
end

Fields and references can be configured dynamically, but the classes and event sets themselves must be configured with an additional Fauna.schema block (normally placed in config/initializers/fauna.rb):

Fauna.schema do
  with Pig do
    # Add a custom event set
    event_set :visions
  end

  with Vision
end

Install your schema on the server via the fauna:migrate Rake task, or directly from the Rails console:

Fauna::Client.context(Fauna.connection) do
  Fauna.migrate_schema!
end

Make sure to do this at least once, as well as every time you change the schema definition:

Users Class

class Fauna::User
  # Extend the User class with a custom field
  field :pockets
end

# Create a user, fill their pockets, and delete them.
Fauna::Client.context($fauna) do
  taran = Fauna::User.new(
    email: "taran@example.com",
    password: "secret")

  taran.save!
  taran.pockets = "Piggy treats"
  taran.save!
  taran.destroy
end

Custom Classes

# Create, find, update, and destroy Pigs.
Fauna::Client.context($fauna) do
  @pig = Pig.create!(name: "Henwen", unique_id: "henwen")

  @pig = Pig.find(@pig.id)
  @pig.update(title: "Oracular Swine")

  @pig.title = "Most Illustrious Oracular Swine"
  @pig.save!

  @pig.destroy
end

Event Sets

Event Sets are high-cardinality, bidirectional event collections. Event sets must be declared in the Schema.

Fauna::Client.context($fauna) do
  @pig = Pig.create!(name: "Henwen", unique_id: "henwen")

  @vision = Vision.create!(pronouncement: "In an ominous tower...")
  @pig.visions.add @vision

  page = @pig.visions.page(:size => 2)
  page.events.first.resource # => @vision

  next_page = @pig.visions.page(:size => 2, :before => page.before)
  prev_page = @pig.visions.page(:size => 2, :after => page.after)
end

References

References are single or low-cardinality, unidirectional, and have no event log. They are declared dynamically, in the class.

class Vision
  # References can be configured dynamically, like fields
  reference :pig
end

Fauna::Client.context($fauna) do
  @vision.pig # => @pig
  @vision.pig_ref # => "instances/1235921393191239"
end

Further Reading

Please see the Fauna REST Documentation for a complete API reference, or look in /test for more examples.

Contributing

GitHub pull requests are very welcome.

LICENSE

Copyright 2013 Fauna, Inc.

Licensed under the Mozilla Public License, Version 2.0 (the "License"); you may not use this software except in compliance with the License. You may obtain a copy of the License at

http://mozilla.org/MPL/2.0/

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.