home shape
right blob img min
ArangoDB Foxx logo bg

ArangoDB Foxx

Foxx is a JavaScript framework for writing data-centric HTTP microservices that run directly inside of ArangoDB.

Traditionally, server-side projects were developed as standalone applications that guide communications between the client-side front-end and the database back-end. Through the Foxx Microservice Framework, ArangoDB allows application developers to write their data access and domain logic as microservices and running directly within the database with native access to in-memory data.

Unlike this approach to storing logic in databases, these microservices can be written as regular, structured JavaScript applications, easily distributed and version controlled. Foxx can handle anything from optimized REST endpoints performing complex data access to standalone applications running directly inside the database.

 

router.get((req, res) => {
  res.write(`
    Hello :D
    This is your database speaking.
  `)
})

Benefits

Benefits of using Foxx include:

  • Unified Data Storage Logic: Standardizing your data access and storage logic on a consistent domain specific API, allowing clients to access the database using the same performance optimized queries.
  • Reduced Network Overhead: Running inside of ArangoDB itself, Foxx allows you to bundle database queries with the logic necessary to handle requests in one place, reducing the number of requests your applications need to send to the database.
  • Restricting Access to Sensitive Data: Moving the authentication and authorization processes from your application to ArangoDB, Foxx lets you isolate sensitive information, ensuring that it never has to leave the database.
  • Other Features: Foxx supports additional features, including automatically generating documentation with Swagger, full-stack JavaScript, infinite extensibility and integration with external services.

Unified Data Storage Logic

In the real world, different types of services use a given API, often implemented using different technologies and written in different languages. In practice, different clients tend to implement the same data storage and data access logic over and over again. This leads to subtle differences in behavior and performance and huge maintenance costs over time, as internal data models change and clients evolve.

By moving the details of your data access and storage logic inside the database, you gain a consistent domain specific API for your clients. This shields those clients from changes to your internal data structures. Every client can now access your database using the same performance optimized queries.

const graphql = require('graphql-sync')
router.post('/gql', (req, res) => {
  const result = graphql(schema, req.body)
  if (result.errors) {
    const errors = result.errors.map(e => formatError(e))
    res.throw('bad request', {extra: {errors}})
  }
  res.json(result)
})

Reduced Network Overhead

Often applications need to make several requests of the database in order to collect the information they need for various operations. When the application and the database run on the same host, this isn’t an issue. But, when the application and the database run on different hosts, it introduces a performance bottleneck in the network connection between them.

Using REST API’s you can mitigate some of this in a clean and predictable way, but not every database interaction works well when expressed in terms of discrete resources. Even when using query languages, there are some tasks that a single request simply won’t solve. And, modern approaches such as GraphQL can make this even worse, requiring careful optimizations to prevent your application from making dozens of requests in complex queries.

Foxx literally runs inside of ArangoDB itself. This allows you to bundle both the database query and the logic needed to handle a request in one place. If you want to support GraphQL, for instance, you can resolve GraphQL queries right inside your Foxx microservice. And, because all your data access logic lives in one place, you can wrap the whole process in transactions.

Restricting Access to Sensitive Data

Many applications require direct access to sensitive information, such as user credentials or private data. They need this access because they handle the authentication and authorization process on the client’s side, rather than on the database. This means that if an attacker compromises the application, they can execute arbitrary requests on the database to gain illegitimate access to any data the application itself can access.

With Foxx, you can move the authentication and authorization processes from your application to ArangoDB. Your application no longer needs to handle or otherwise access extremely sensitive information. A Foxx microservice can process this information server-side and only return the results to your application.

Other Features

.summary('Swagger documentation')
.description('Document your services where you implement them.')
background img
right blob long

Generate Documentation

The Foxx API makes it easy for you to provide nice documentation for your Foxx microservices.  The same methods you use to specify parameter validation can also serve to document those parameters.  No need for special comments or separate files: just document your routes right where you define them.  If you need something more flexible than the generated default documentation, you can expose the Swagger 2.0 JSON metadata for any installed service and provide your own front-end.

Easy to Learn

The Foxx Framework in ArangoDB 3.0 was rewritten to make it even easier to learn and master. It has become even more flexible. You no longer need to work with repositories and wrappers, but can instead use the database API directly and write your queries in AQL. define your endpoints using straightforward routers and enhance them with Express.js-like middleware.

module.context.use(sessions({
  storage: module.context.collection('sessions'),
  transport: 'cookie'
}))

Full-stack JavaScript

Web browsers speak JavaScript, Node speaks JavaScript, Foxx speaks JavaScript: If your application runs on the Web, you likely already use JavaScript.  In cases where your application compiles to JavaScript, (such as with CoffeeScript or TypeScript), or uses experimental features, (such as those provided by Babel), you can use your existing toolchain to build Foxx services.

Batteries Included

Need sessions? Pick between stateless JWT and database backed, decide whether you want cookies or a header (or both!) and you’re ready to go. Your prototype is missing some basic password logic? Foxx has your back. User management? It’s trivial to roll your own and we’ll show you how.

	
require('dependencies')
background img

It's just code

Foxx services are not plugins or stored procedures.  Rather, they are JavaScript packages consisting of source code files.  This means that it’s easy to use the same version control, code reviews and continuous integration systems with Foxx that you’re already using with your application code.

router.get('/hello/:name', (req, res) => {
  res.write(`Hello ${req.pathParams.name}!`)
})
.pathParam('name', joi.string().required())

Infinitely Extensible

When you need more than what Foxx supplies through built-ins and bundled modules, you can install additional JavaScript modules from npm, as you would when using Node.js. When your application outgrows a single service, you can install another. You can even tell services about each other, allowing them to interact directly by exposing JavaScript API’s. Plus, there’s the Fox Store, which lets developers in the Foxx community publish and exchange open source microservices with one-click installations.

 

right blob img min

Plays Well with Others

For non-trivial applications, it may not be feasible to put all your eggs in one basket. With Foxx, you don’t have to. Whether you want Foxx to serve as the entire back-end to a single-page application serving static assets or you need several small Foxx microservices to a scalable infrastructure, ArangoDB Foxx has you covered.

queue.push({ 
  mount: module.context.mount, 
  name: 'send-email' 
}, { 
  to: 'cto@startup.cool', 
  subject: `Let's talk about microservices` 
})

Integrate external services

With Foxx you can work with other services over HTTP.  Using the build-in job queue, you can integrate third-party services in the background, such as transaction email providers, user analytic services and error loggers.  You can also develop your own scripts and execute them as workers