ArangoDB Object Modeling for Node.js, Foxx and Modern Web Browsers
Inspired by Mongoose. Built using Tang, Joi and ArangoJS
Orango is an Object Data Modeler (ODM) that provides the following features:
- Central connectivity to ArangoDB
- Automated creation of collections and indexes
- Create schemas for data
- Interact with models to handle data-centric functionality
- Pre-populate database
- and more...
- Ease of use
- Model-driven data
- Focus on data instead of queries
- Optimized query creation
- Validation prevents bad data from being injected into database
- Cleaner interfaces
- Single point of change for bug fixes, features, etc
- Computed properties on return values
- Default values
- and more...
(In Progress) Official documentation can be found at orango.js.org.
Orango is in alpha
. Working on bug fixes, cleanup, documentation and examples.
First be sure you have ArangoDB and Node.js installed. You can easily install ArangoDB using the official docker container. There is also a docker-compose.yml
file that is in the tools
directory if you want to copy it to your project, then all you have to do is run the code below to start an instance of ArangoDB.
$ docker-compose up -d
Next, install Orango from the command line using npm
:
$ npm install orango
// Using Node.js `require()`
const orango = require('orango')
// Using ES6 imports
import orango from 'orango'
First, we need to define a connection. If your app uses only one database, you should use orango.connect()
. If you need to create additional connections, use orango.get( instanceName:String ).connect()
.
The method connect(db:String="_system", [{url:String="http://localhost:8529", username:String, password:String}])
takes database name with options to establish a connection. Otherwise, it will use the default values.
const orango = require('orango')
const { EVENTS } = orango.CONSTS
orango.events.on(EVENTS.CONNECTED, () => {
console.log('Orango is connected!')
})
async function main() {
await orango.connect()
}
main()
Orango buffers model definitions, so they can be defined before or after a connection is established.
const BlogPost = orango.Schema({
author: String,
title: String,
body: String,
date: Date
})
orango.model('blog', BlogPost)
Aside from defining the structure of your documents and data types, a Schema handles the definition of:
- Validators
- Default values
- Indexes
- Middleware
- Methods definitions
- Statics definitions
- Computed properties
- Pre and post hooks
- Real-joins (thanks ArangoDB!)
- Custom queries
- Filtering out unknown properties
- Joi syntax support
The following example shows some of these features:
const orango = require('orango')
const Joi = require('joi')
const { HOOKS } = orango.CONSTS
const UserSchema = orango.Schema({
firstName: String,
lastName: String,
email: Joi.string().email(), // Joi can be used directly
age: { type: Number, min: 18 }, // JSON gets converted to Joi data types automatically
bio: { type: String, regex: /[a-z]/ },
updatedAt: Date
}, {
strict: true, // unknown properties will be filtered out
indexes: [ // create indexes for items we will query against
{
type: 'hash',
fields: ['email']
},
{
type: 'skipList',
fields: ['firstName']
},
{
type: 'skipList',
fields: ['lastName']
}
]
})
// static methods
UserSchema.statics.findByEmail = async function(email) {
return this.findOne({ email })
}
// computed properties
UserSchema.computed.name = function() {
return this.firstName + ' ' + this.lastName
}
const User = orango.model('User', UserSchema)
// hooks
User.on(HOOKS.UPDATE, payload => {
payload.data.updatedAt = Date.now()
})
// ... example of using it in a router ... //
app.get('/user', async (req, res) => {
let user = await User
.findByEmail(req.query.email)
.computed()
.id()
res.send(user)
})
200 Ok
{
"id": "163706"
"name": "John Smith",
"firstName": "John",
"lastName": "Smith",
"email": "john.smith@gmail.com",
"age": 26,
"bio": "Likes mountain biking and camping",
"updatedAt": "2018-12-02T16:04:10.026Z"
}
Go to https://orango.js.org for detailed documentation and tutorials.
A growing set of examples are available here.
- Create a proper CHANGELOG
- Bug fixes
- Documentation
- Examples
- autoIndex in schema - will create indexes as properties become part of query
- Support upsert option
- Getter / Setters in schema
- Integrate Arango Chair
- web browser compatible
- Better error handler / dispatching
- Upgrade to TypeScript
- Add lint support
This library is under the MIT license. See LICENSE