Framework for setting up RESTful JSON APIs with NodeJS.

Overview

Restberry works with both Express and Restify!

Framework for setting up RESTful JSON APIs with NodeJS. Define your models and setup CRUD API calls without needing to write any code (see Usage). All API calls will handle and identify issues and throw necessary HTTP responses and easy to debug error responses. Restberry also handles authentication and permission checks and throws appropriate errors.

Install

npm install restberry

Example

See example for a detailed documentation of how you setup a Restberry app.

Usage

var restberry = require('restberry');

restberry
    .config({
        apiPath: '/api/v1',
        port: 5000,
    })
    .listen();

restberry.model('Foo')
    .schema({
        name: {type: String},
    })
    .routes
        .addCreateRoute()
        .addReadManyRoute();

restberry.model('Bar')
    .schema({
        foo: {type: restberry.odm.ObjectId, ref: 'Foo'},
        name: {type: String},
    })
    .routes
        .addCRUDRoutes({
            parentModel: 'Foo',
        });

NOTE: By default, Restberry integrates with ExpressJS and Mongoose but it can be hooked up with other packages. See more usages in the tests and dependent packages like:

Response examples

All these responses below are automatically handled without needing to write any additional code.

  • 200 OK
2014-05-11T11:55:53.916Z|172.16.122.129|GET|/api/v1/foos/536f6549e88ad2b5a71ffdc6|<{}>
2014-05-11T11:55:53.920Z|172.16.122.129|200|<{
  "foo": {
    "href": "/api/v1/foos/536f6549e88ad2b5a71ffdc7",
    "id": "536f6549e88ad2b5a71ffdc7",
    "name": "test"
  }
}>
  • 201 CREATED
2014-05-11T11:55:54.210Z|172.16.122.129|POST|/api/v1/foos|<{
  "name": "test"
}>
2014-05-11T11:55:54.210Z|172.16.122.129|201|<{
  "foo": {
    "href": "/api/v1/foos/536f654ae88ad2b5a71ffdcb",
    "id": "536f654ae88ad2b5a71ffdcb",
    "name": "test"
  }
}>
  • 204 NO CONTENT
2014-05-11T11:55:52.575Z|172.16.122.129|DELETE|/api/v1/foos/536f6548e88ad2b5a71ffdb7|<{}>
2014-05-11T11:55:52.579Z|172.16.122.129|204|

NOTE: See restberry-errors for possible error responses.

Authentication

See restberry-passport.

Routing

restberry.model('Foo')
    .routes
        .addCreateRoute()  // POST /foos
        .addDeleteRoute()  // DELETE /foos/:id
        .addPartialUpdateRoute()  // POST /foos/:id
        .addReadManyRoute()  // GET /foos
        .addReadRoute()  // GET /foos/:id
        .addUpdateRoute()  // PUT /foos/:id
        .addCRUDRoutes()  // All of the above...

Handle action query strings like this:

restberry.model('Foo')
    .routes
        .addPartialUpdateRoutes({
            actions: {
                build: function(req, res, next) {
                    ...
                },  // POST /foos/:id?action=build
            },
        })

And Handle parent models like this:

restberry.model('Foo')
    .routes
        .addCreateRoutes({
            parentModel: restberry.model('Bar'),
        })  // POST /bars/:id/foos

NOTE: this can only be applied to ReadMany and Create.

You can also create custom routes. The possible configurations you can make are:

restberry
    .routes
        .addCustomRoutes({
            action: function(req, res, next) {
                ...
            },
            apiPath: '/api/v1',  // overrides the one set on Restberry
            actions: { },
            loginRequired: false,  // should authenticate the request
            method: 'GET',  // choices: DELETE, GET, POST, PUT
            parentModel: restberry.model('Bar'),
            path: '/path/to',  // the path of the route, will append apiPath
            postAction: function(json, req, res, next) {
                ...
            },  // will be executed after action
            preAction: function(req, res, next) {
                ...
            },  // will be executed before action
            verbose: false,  // will print the API call on initiation
        })

NOTE: you can set these properties to all the predefined API definitions, you won't be able to override action however.

Run the tests

npm test

Further reading

I have written an article series on RESTful JSON API design which this package is base upon, you can find the three parts here: part 1, part 2 and part 3.

Contact

I'm really interested to here what you guys think of Restberry, especially if you have any suggestions to improve the package. Please contact me at [email protected].

Comments
  • Delete child schema

    Delete child schema

    It's possible, when call on delete /api/sci/:id, delete to /api/sci/:id/biens ? Or i should delete biens manually with delete /api/biens/:id ?

    if it's second solution, it's uncomfortable.

    opened by lobor 12
  • Return full objects from .addReadManyRoute()

    Return full objects from .addReadManyRoute()

    Is it possible to have the .addReadManyRoute() return full objects? I ran the example, created a few Cities, and added .addReadManyRoute() to the City model.

    When I open /api/v1/cities, this is returned (even though those cities have a name and location properties):

    {
      hrefs: {
        current: "/api/v1/cities?offset=0&limit=10",
        first: null,
        next: null,
        prev: null,
        last: null
      },
      offset: 0,
      limit: 10,
      total: 2,
      cities: [
        {
          href: "/api/v1/cities/56df653d8e6466c730803693",
          id: "56df653d8e6466c730803693"
        },
        {
          href: "/api/v1/cities/56df6581ad47d6f230a8e779",
          id: "56df6581ad47d6f230a8e779"
        }
      ]
    }
    
    opened by petarjs 5
  • Append posix to 'path' requires so that restberry can work on Windows.

    Append posix to 'path' requires so that restberry can work on Windows.

    When using restberry on Windows path use '' separator for join method so the path looks like /api/v1\cities:id which causes a RegExp error on launch.

    Appending posix forces path to use / as separator for join method

    opened by AurelienPecqueur 4
  • Cannot read property 'ref' of undefined

    Cannot read property 'ref' of undefined

    Hi,

    I have this schema,

    {
            name: {
                type: String,
                required: true,
                index: {
                    unique: true
                }
            },
            rcs: {
                type: Number,
                required: true
            },
            date_immatriculation: {
                type: Date,
                required: true
            },
            capital: {
                type: Number,
                required: true
            },
            naf: {
                type: String,
                required: true
            },
            adress: {
                type: String,
                required: true
            },
            cp: {
                type: Number,
                required: true
            },
            city: {
                type: String,
                required: true
            },
            nb_part: {
                type: Number,
                required: true
            },
            associes:[{
                nom: {
                    type: String,
                    required: true,
                },
                prenom: {
                    type: String,
                    required: true
                },
                address: {
                    type: String,
                    required: true
                },
                cp : {
                    type: Number,
                    required: true
                },
                city: {
                    type: String,
                    required: true
                },
                birthday: {
                    type: Date,
                    required: true
                },
                city_birthday: {
                    type: String,
                    required: true
                },
                np_part: {
                    type: Number,
                    required: true
                },
                percent_part: {
                    type: Number,
                    required: true
                }
            }]
        }
    

    and when get the data i have this error

    /Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry-mongoose/lib/index.js:107
            } else if (field.caster && field.caster.options.ref) {
    
    TypeError: Cannot read property 'ref' of undefined
        at RestberryMongoose.getFieldsOfModels (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry-mongoose/lib/index.js:107:56)
        at RestberryModel.getFieldsOfModels (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry/lib/model.js:160:24)
        at RestberryModel.getFieldNamesOfModel (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry/lib/model.js:164:10)
        at RestberryObj.__isAuthorized (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry/lib/obj.js:30:20)
        at RestberryObj.isAuthorized (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry/lib/obj.js:110:18)
        at RestberryObj.toJSON (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry/lib/obj.js:249:10)
        at utils.forEachAndDone.json (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry/lib/objs.js:34:13)
        at Object.module.exports.forEachAndDone (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry/node_modules/restberry-utils/lib/index.js:55:13)
        at RestberryObjs.toJSON (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry/lib/objs.js:33:11)
        at /Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry/node_modules/restberry-router-crud/lib/controller.js:97:26
        at Promise.<anonymous> (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry/lib/model.js:85:13)
        at Promise.<anonymous> (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry-mongoose/node_modules/mongoose/node_modules/mpromise/lib/promise.js:177:8)
        at Promise.emit (events.js:107:17)
        at Promise.emit (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry-mongoose/node_modules/mongoose/node_modules/mpromise/lib/promise.js:84:38)
        at Promise.fulfill (/Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry-mongoose/node_modules/mongoose/node_modules/mpromise/lib/promise.js:97:20)
        at /Users/lionelbertrand/Documents/locloud/backfront/node_modules/restberry-mongoose/node_modules/mongoose/lib/query.js:1058:26
    
    opened by lobor 4
  • Added check for path.posix, so restberry can still work on node version prior to 0.12

    Added check for path.posix, so restberry can still work on node version prior to 0.12

    Added check for path.posix, so restberry can still work on node version prior to 0.12

    To run restberry on Windows you will have to use node >= 0.12.

    opened by AurelienPecqueur 1
  • Easier way to expand the Restberry response

    Easier way to expand the Restberry response

    Should have a method so you can call expand of a model or an object and have that name be added to the expand list:

    restberry.model('Feed').expand()
    

    instead of

    restberry.model('Feed').options().addExpand(restberry.model('Feed').singularName())
    
    enhancement 
    opened by materik 1
  • Change to a promise pattern for models and objects

    Change to a promise pattern for models and objects

    restberry.model('Feed')
        .find({id: 1})
        .toJSON(function(json) {
            ...
        })
        .onSuccess(function(feed) {
            ...
        })
        .onError(function(error) {
            ...
        })
    

    instead of

    restberry.model('Feed').find({id: 1}, function(feed) {
        feed.toJSON(function(json) {
            ...
        })
    }, function(error) {
        ...
    })
    
    enhancement 
    opened by materik 0
  • Is it possible to use on a Relational Database

    Is it possible to use on a Relational Database

    First a question: is it possible to do this on relational databases as well? For example mysql/maria or postgres?

    Next I have some ideas: I really like the idea of declaring what it should do, instead of writing how it should do it. Especially for writing a light backend for a SPA frontend for example

    I've been working on something alike where you define an object on which the request should match and then some optional middleware. It's easier to show it by example:

    app.on({ method: 'POST' }, function(req, res, next) { 
      // perform some logic (authorization rules for example)
      next(); // calling next will eventually call the middleware that handles the database
    }
    

    This way you define what it should do instead of on which route etc. If you want I can share a very premature draft with you.

    question 
    opened by alber70g 2
  • Unable to update embedded array in model

    Unable to update embedded array in model

    Embedded array in model isn't saved on updates, which is consistent with the FAQ number 1 in moongose.

    The following is the simplified version of the code:

    var restberry = require('restberry');
    
    restberry.model('AuthItem')
        .schema({
            name: {type: String, required: true},
            children: [{type: restberry.odm.ObjectId, ref: 'AuthItem'}],
        })
        .routes
            .addCRUDRoutes();
    

    Request:

    PUT /api/v1/authitems/57a8294b338d9e5221638665
    
    {
        "name": "admin",
        "children": ["57a8294b338d9e5221638665"]
    }
    

    Any solution?

    question 
    opened by rizkiarm 1
Owner
Restberry
Restberry
Component based MVC web framework for nodejs targeting good code structures & modularity.

Component based MVC web framework for nodejs targeting good code structures & modularity. Why fortjs Based on Fort architecture. MVC Framework and fol

Ujjwal Gupta 47 Sep 27, 2022
Fake APIs for prototypes & automated tests.

Interfake is a tool which allows developers of client-side applications of any platform to easily create dummy HTTP APIs to develop against. Let's get started with a simple example.

Daniel Hough 805 Dec 23, 2022
Actionhero is a realtime multi-transport nodejs API Server with integrated cluster capabilities and delayed tasks

Actionhero The reusable, scalable, and quick node.js API server for stateless and stateful applications NPM | Web Site | Latest Docs | GitHub | Slack

Actionhero 2.3k Jan 4, 2023
Zeronode - minimal building block for NodeJS microservices

Zeronode - minimal building block for NodeJS microservices Why Zeronode? Installation Basics Benchmark API Examples Basic Examples Basic Examples [Adv

Steadfast 120 Oct 21, 2022
AWS Lambda router for NodeJS

AWS Lambda Router for NodeJS A collection of tools to handle ApiGateway requests and direct function invocation calls on AWS Lambda. Use it as a stand

Dumitru Glavan 11 Apr 22, 2019
The React Framework

Next.js Getting Started Visit https://nextjs.org/learn to get started with Next.js. Documentation Visit https://nextjs.org/docs to view the full docum

Vercel 98.6k Jan 5, 2023
Fast, unopinionated, minimalist web framework for node.

Fast, unopinionated, minimalist web framework for node. const express = require('express') const app = express() app.get('/', function (req, res) {

null 59.5k Jan 5, 2023
The Intuitive Vue Framework

Build your next Vue.js application with confidence using Nuxt: a framework making web development simple and powerful. Links ?? Documentation: https:/

Nuxt 41.8k Jan 9, 2023
A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications on top of TypeScript & JavaScript (ES6, ES7, ES8) 🚀

A progressive Node.js framework for building efficient and scalable server-side applications. Description Nest is a framework for building efficient,

nestjs 53.2k Dec 31, 2022
Realtime MVC Framework for Node.js

Website Get Started Docs News Submit Issue Sails.js is a web framework that makes it easy to build custom, enterprise-grade Node.js apps. It is design

Balderdash 22.4k Dec 31, 2022
Fast and low overhead web framework, for Node.js

An efficient server implies a lower cost of the infrastructure, a better responsiveness under load and happy users. How can you efficiently handle the

Fastify 26k Jan 2, 2023
The Simple, Secure Framework Developers Trust

@hapi/hapi The Simple, Secure Framework Developers Trust Build powerful, scalable applications, with minimal overhead and full out-of-the-box function

hapi.js 14.1k Dec 31, 2022
🚀 The Node.js Framework highly focused on developer ergonomics, stability and confidence

Sponsored by FOSS United is a non-profit foundation that aims at promoting and strengthening the Free and Open Source Software (FOSS) ecosystem in Ind

AdonisJS Framework 13.4k Dec 31, 2022
:rocket: Progressive microservices framework for Node.js

Moleculer Moleculer is a fast, modern and powerful microservices framework for Node.js. It helps you to build efficient, reliable & scalable services.

MoleculerJS 5.5k Jan 4, 2023
MVC framework making it easy to write realtime, collaborative applications that run in both Node.js and browsers

Derby The Derby MVC framework makes it easy to write realtime, collaborative applications that run in both Node.js and browsers. Derby includes a powe

DerbyJS 4.7k Dec 23, 2022
Node.js framework

Node.js framework Total.js framework is a framework for Node.js platfrom written in pure JavaScript similar to PHP's Laravel or Python's Django or ASP

Total.js 4.2k Jan 2, 2023
🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈

Midway - 一个面向未来的云端一体 Node.js 框架 English | 简体中文 ?? 欢迎观看 Midway Serverless 2.0 发布会回放: https://www.bilibili.com/video/BV17A411T7Md 《Midway Serverless 发布

Midway.js 6.3k Jan 8, 2023
:evergreen_tree: Modern Web Application Framework for Node.js.

Trails is a modern, community-driven web application framework for Node.js. It builds on the pedigree of Rails and Grails to accelerate development by

Trails 1.7k Dec 19, 2022
Marble.js - functional reactive Node.js framework for building server-side applications, based on TypeScript and RxJS.

Functional reactive Node.js framework for building server-side applications, based on TypeScript and RxJS. Ecosystem Name Description @marblejs/core F

Marble.js 2.1k Dec 16, 2022