zeph·yr noun
a breeze from the west- a lightweight fabric
Zephyr is a lightweight personal cloud framework that makes it easy to build scalable, real-time apps powered by personal data.
Personal cloud is a relatively new term. In concept, it's a server that provides authentication and access to a user's personal data. Think of Facebook and Dropbox as proto-personal clouds. Each one provides some form of authentication and an API for fetching and storing data on behalf of the user. The problem with existing proto-personal clouds is that they are neither standardized nor portable which means it's not ideal for users and more work for app developers to integrate.
Learn more about Personal Clouds.
The goal of Zephyr is to create a simple personal cloud framework that provides standardized APIs for authenticating, fetching, normalizing, storing, and sharing data between personal clouds and within a scalable app architecture.
Support is being added to Zephyr for both existing personal data sources (Facebook, Dropbox, Gmail, etc.) as well as fully compliant personal clouds.
Zephyr is designed to be used either as your app's backend or as a personal data cache layer for your existing apps.
Zephyr is a new project but moving quickly to solve real world app developer problems.
- Router – config and basic router [done]
- CloudStore – token based authentication, GET, PUT, DELETE [done]
- Tests – basic coverage for CloudStore [done]
- Example Apps – Chat [done], data browser [WIP]
- 3rd Party API Support
- Singly for fetching social and personal data [WIP]
- remoteStorage for unhosted apps [WIP]
- connectors for Dropbox, Facebook, Twitter, Gmail, etc. [not started]
Zephyr is composed of several modular components that interact via HTTP APIs.
Components:
- Router: API endpoint that routes requests to other components
- CloudStore: key/value data store with OAuth security layer and notification events
- Pub/Sub: webhook callback engine for distributed event notification
- Engines: pluggable components to fetch social data, provide additional services, etc.
Each component is defined by a RESTful API and is completely replaceable by anything that provides the same API. Most components run behind a firewall and talk to each other on the internal network. Components can be spread out across any number of servers or run on a single server.
- Erlang R15B03+ for high-performance core components
- Postgres 9.1+ with hstore extension for data store
- Node.js 0.8+ for apps, tests, client libraries, etc.
Zephyr runs on OSX and Linux. Windows has not yet been tested.
OSX Quick Install
brew install erlang
brew install postgres
brew install nodejs
# see Install Guide for postgres pg_hba.conf issues
Install Guide for Linux and detailed instructions
# make sure postgres is already running
git clone https://github.com/airships/zephyr.git
cd zephyr
make setup
script/zephyr start
make test
Configuration options are in config directory files. When an option is changed, recompile and restart services.
# reapply config and recompile
make
# restart services
script/zephyr restart
Config Guide for options and details
# start console in foreground
script/zephyr console
# start as service
script/zephyr start
# stop service
script/zephyr stop
# restart service
script/zephyr restart
When Zephyr starts, it runs two data services:
- Data API
- Token Service
The Data API provides RESTful access to data. The Token Service allows for the creation and deletion of access tokens. For security reasons, the Token Service listens on a different port and (optionally) network interface.
Add Auth Token
An auth token is required to access data.
curl --request PUT --header "Content-Type: application/json" --data "{\"\":\"rw\"}" --verbose http://127.0.0.1:10004/tokens/SECRET
In browser or curl, GET http://127.0.0.1:10002/*?token=SECRET which should return an empty JSON object.
The token can be passed in as a cookie or query param.
PUT
curl --data "{\"foo\":\"bar\"}" --request PUT --header "Content-Type: application/json" --verbose http://127.0.0.1:10002/foo/bar/baz?token=SECRET
GET
curl --verbose http://127.0.0.1:10002/foo/bar/baz?token=SECRET
DELETE
curl --request DELETE --verbose http://127.0.0.1:10002/foo/bar/baz?token=SECRET
Note that PUT is a merge operation for objects. This makes it easy for clients to update specific attributes of an existing object without needing to send the entire object.
curl --data "{\"foo\":\"bar\"}" --request PUT --header "Content-Type: application/json" --verbose http://127.0.0.1:10002/foo/bar/baz?token=SECRET
curl --data "{\"new\":\"bar\"}" --request PUT --header "Content-Type: application/json" --verbose http://127.0.0.1:10002/foo/bar/baz?token=SECRET
curl --verbose http://127.0.0.1:10002/foo/bar/baz?token=SECRET
# Returns:
# {
# "foo": "bar",
# "new": "bar"
# }
To replace the entire object, use REPLACE or do a DELETE then PUT.
API tests are written in Node.js mocha
# run tests
make test
Zephyr must be already running for the tests to pass. Tests are run against the same database as development but on a guaranteed unique test branch that is deleted at the end of the tests.
API and Reference documentation are in the wiki.
- Google+ Community – get quick answers from the community
- Troubleshooting – wiki page for common issues
Erlang compilation errors (usually rebar errors) are typically caused by having the wrong version of Erlang/OTP installed. Refer to Troubleshooting for help.
Join the Google+ Community or submit a pull request.
We especially appreciate hearing about your app ideas and how we can help make your life easier as a developer.