Rapid API Development ArangoDB Foxx
-
Upload
michael-hackstein -
Category
Software
-
view
490 -
download
2
Transcript of Rapid API Development ArangoDB Foxx
by Michael Hackstein
@mchacki
Rapid API Development ArangoDB Foxx
Michael Hackstein @mchacki
• Member of ArangoDB Core Team
• web front-end
• graph features
• Organizer of cologne.js
• Master’s Degree(spec. Databases andInformation Systems)
Classical Web Applications
Application Logic
Single Page Web Applications
Application Logic
The Idea
• What if we could talk to the database directly?
• It would only need an API
• What if we could define this API in JavaScript?
Single Page Web Applications
This doesn‘t mean its a Rails/… Killer
Client Server DB
Client Server (optional)
DB with Foxx
What is ?• a multi-model database (document store & graph database)
• is open source and free (Apache 2 license)
• offers convenient queries (via HTTP/REST and AQL)
• offers high performance and is memory efficient
• uses JavaScript throughout (V8 built into server)
• doubles as a web and application server (Foxx)
• offers many drivers for a wide range of languages
• is easy to use with web frontend and good documentation
• enjoys good professional as well as community support
• and recently added sharding in Version 2.0.
/\ (~( ) ) /\_/\ ( _-----_(@ @) ( \ / /|/--\|\ V " " " "
• … a feature of ArangoDB since 1.4
• … an easy way to define REST APIs on top of ArangoDB
• … a toolset for developing your single page web application
• … not requiring any special code on the client side – use it with Angular, Backbone, Ember,…
Foxx is…
Why another solution?
• ArangoDB Foxx is streamlined for API creation – not a Jack of all trades
• There‘s no communication overhead between (serverside) application and database
• It is designed for front end developers: Use JavaScript, you already know that
Foxx.Controller
Foxx = require("org/arangodb/foxx");
Foxx = require("org/arangodb/foxx");
controller = new Foxx.Controller(appContext);
Foxx = require("org/arangodb/foxx");
controller = new Foxx.Controller(appContext);
controller.get("/users", function(req, res) {});
Foxx = require("org/arangodb/foxx");
controller = new Foxx.Controller(appContext);
controller.get("/users", function(req, res) { res.json({ hello: "world" });});
Parameterize the routes
• You may want a route like `users/:name`…
• …and then access the value of `name` easily
Foxx = require("org/arangodb/foxx"); !controller = new Foxx.Controller(appContext); !controller.get("/users", function(req, res) { res.json({ hello: "world" }); });
Foxx = require("org/arangodb/foxx"); !controller = new Foxx.Controller(appContext); !controller.get("/users ", function(req, res) { res.json({ hello: "world" }); });
/:name
Foxx = require("org/arangodb/foxx"); !controller = new Foxx.Controller(appContext); !controller.get("/users ", function(req, res) { res.json({ hello: "world" }); });
req.params("name");
/:name
• In your Foxx.Controller you describe your routes
• But your application can consist of multiple Foxx.Controllers
• … and you also want to deliver assets and files
Manifest.json
{ "name": "my_website", "version": "1.2.1", "description": "My Website with a blog and a shop", "thumbnail": "images/website-logo.png", ! "controllers": { "/blog": "apps/blog.js", "/shop": "apps/shop.js" }, ! "assets": { "application.js": { "files": [ "vendor/jquery.js", "assets/javascripts/*" ] } } }
{ "name": "my_website", "version": "1.2.1", "description": "My Website with a blog and a shop", "thumbnail": "images/website-logo.png", ! "controllers": { "/blog": "apps/blog.js", "/shop": "apps/shop.js" }, ! "assets": { "application.js": { "files": [ "vendor/jquery.js", "assets/javascripts/*" ] } } }
{ "name": "my_website", "version": "1.2.1", "description": "My Website with a blog and a shop", "thumbnail": "images/website-logo.png", ! "controllers": { "/blog": "apps/blog.js", "/shop": "apps/shop.js" }, ! "assets": { "application.js": { "files": [ "vendor/jquery.js", "assets/javascripts/*" ] } } }
More
• Define a setup and teardown function to create and delete collections
• Define lib to set a base path for your require statements
• Define files to deliver binary data unaltered
Documentation as a first class citizen
Annotate your Routes
• For Documentation
• But it is also used for validation
controller.get("/users/:name", function(req, res) { res.json({ hello: req.params("name"); }); });
controller.get("/users/:name", function(req, res) { res.json({ hello: req.params("name"); }); }) .pathParam("name", { description: "Name of the User", dataType: "string" });
;
controller.get("/users/:name", function(req, res) { res.json({ hello: req.params("name"); }); }) .pathParam("name", { description: "Name of the User", dataType: "string" });
/** What's my name? * * This route knows it. */
Automatically generate Swagger Docs
Foxx.Repository and Foxx.Model
Domain Models Persistence
Foxx.Model Foxx.Repository
Foxx.Model Foxx.Repository
• Representation of the data • Convenience Methods • Validation
• Save and Retrieve Data • Simple Queries • Define your own queries
Why this separation?• It doesn‘t violate the SRP like ActiveRecord
• In a lot of cases you can use the standard Repository or Model and don‘t need your own
• It‘s great for testing
• You can mock the collection and the model prototype to test your Repository
• You don‘t need to mock anything to test your model
Foxx.Model
• The constructor takes a hash of attributes
• Access the attributes with get, set and has
• The forDB will be used to write the data into the database
• Use forClient to prepare the data for delivery
Foxx.Repository
• The constructor takes an arangodb-collection and the prototype of the model
• save for example expects an instance of the model
• firstExample finds a suitable dataset and returns it as an instance of the model
• Other methods: remove, replace, update…
You need more?
• Use Foxx.Repository.extend and Foxx.Model.extend to inherit from the prototype
• Add your own methods
• Your extensions live in separate files
Foxx = require("org/arangodb/foxx");!!MyRepository = Foxx.Repository.extend({
});!!exports.Repository = MyRepository;
byName: function (name) {! return this.byExample({! name: name! });! }
Foxx = require("org/arangodb/foxx");!!MyRepository = Foxx.Repository.extend({
});!!exports.Repository = MyRepository;
Contact
• I am mchacki everywhere:
• @mchacki on Twitter
• mchacki on Github
Thanks
• First Slide version by Lucas Dohmen
• Database icon designed by Romeo Barreto from The Noun Project
• Logos from Node.js, Ruby on Rails, Django, AngularJS, Backbone, Ember and Symfony from the respective projects
• All other icons are from Font Awesome