Midgard

0.9.7 • Public • Published

MIDGARD

Midgard is a REST API code generator. The ultimate goal of Midgard is to generate, from a single JSON object describing the models, a REST API in any languages and frameworks possible. To do its generation, Midgard needs a service file per languages / frameworks. The service file describe how the API should be generated (see below). When you have a service file for the language you want to generate a REST API in, all you have to do is to call Midgard with your models file (see below).

INSTALL

sudo npm install -g Midgard (it currently only works well on linux environments)

Since Midgard is a command line tool, it should be installed globally.

Midgard uses a certain directory structure and it won't be created automatically when you install Midgard (you'll have to do it manually).This is what the directory in which Midgard has been installed should look like:

.
├── bin
│   └── index.js
├── makefile
├── node_modules
│   ├── es6-module-loader
│   ├── handlebars
│   ├── mkdirp
│   ├── q
│   ├── traceur
│   └── underscore
├── package.json
├── README.md
├── services
├── serviceTemplates
│   └── translators
├── src
│   └── compiler.js
└── test
    └── compilerSpec.js

SERVICE FILE

A service file is a description of what will be generated and how it will be generated. The service file is basically just an annoted class that we export.

import {Service} from "compiler/path.js"
 
@Service ({
    executePre:{
        command1: "command to run pre generation"
        , command2: "another command to run pre generation"
        , ...
    }
    , files:{
        name_of_the_file_to_be_generated: {handlebars: "path/to/template.file"}
        ,name_of_the_file_to_be_generated2: {ecmaScript: "path/to/template.file"}
        , ...
    }
    , executePost:{
        command1: "command to run post generation"
        , command2: "another command to run post generation"
        , ...
    }
})
export class myClass {};

The command in the executePre and executePost properties will be executed sequentially so a command can depend on another.

The files are generated either with HandlebarsJS or with a ES6 template literal.

MODELS FILE

Like a service file, a models file is an annoted class with a call to the generator's start function.

import {Model, start} from 'compiler/path.js'
 
@Model([
    {
        /*
          server node
        */
    }
    ,{
        /*
          service node
        */
    }
    ,{
        /*
          collection node
        */
    }
    ,{
        /*
          another collection node
        */
    }
    , ...
])
class myClass {}
start(myClass, 'output/file/folder')

The first object in the model array is the server node. It contains, well..., server informations like the host, the port and the url.

The second object is the service node. This is where we indicate which kind of service we're generating (i.e the service file). Database credential such as the adapter, dsn, user and password are service dependant (they change depending) on wich type of service we're generating) so they will appear in the service node.

The third object (and all those after it) are the collection nodes. This is where you describe the models of your application (collections for mongodb or tables for relational database)

No extensive documentation has been made yet for the on the content of the nodes. Please refer to unit tests for examples of what is possible.

EXECUTING

Once that your Midgard directory structure is set up and that you have a a service and a models file all you have to do to generate your REST API is to execute the following command:

Midgard path/to/models.file

SERVICE FILE EXAMPLE

This is an example of what a service file could/should look like. This service file is what has been use in the latest integration tests of Midgard and serves to generate a REST API for a silex/propel environment. Note that this service file is not fully completed...

import {Service} from "../../src/compiler.js"
 
@Service ({
    executePre:{
    move_composer: "cp $MIDGARD_PATH/serviceTemplates/silex_propel/composer.json .",
    compose:"php $MIDGARD_PATH/serviceTemplates/silex_propel/composer.phar install"
    },
    files:{
        "index.php":{handlebars:"serviceTemplates/silex_propel/index.php"},
        "Propel_model":{handlebars:"serviceTemplates/silex_propel/PHP_Propel_Model.xml"},
        "propel.ext":{handlebars:"serviceTemplates/silex_propel/propel.ext"},
    },
    executePost:{
        configuration: "vendor/bin/propel sql:build",
        modelisation: "vendor/bin/propel model:build"
    }
})
export class silex_propel {};

MODELS FILE EXAMPLE

This is an example of what a models file could/should look like. This models file is what has been use in the latest integration tests of Midgard and serves to generate a REST API for a silex/propel environment. Note that this models file is not fully completed...

import {Model, start} from "/home/gs/midgard-prod/node_modules/Midgard/src/compiler.js";
 
@Model ([
    {
        path:'/public/demo/',
        server: {
            name:'NodeJS',
            host: 'localhost',
            port: 5000,
            url: 'http://localhost',
            description: 'Demo NodeJS',
            cryptoKey: 'k3yb0ardc4t',
            authentication: true
        }
    },
    {
        path: '/public/demo/ROOMS/',
        service: {
            name: "Rooms",
            type: {
                name: 'silex_propel',
                config: {
                            adapter: "mysql",
                            classname: "Propel\Runtime\Connection\ConnectionWrapper",
                            dsn: "mysql:host=localhost;dbname=my_db_name",
                            user: "my_db_user",
                            password: "s3cr3t",
                            attributes: []
                        }
            }
        }
    },
    {
        path: '/public/demo/ROOMS/rooms',
        collection: {
            name: 'rooms'
        },
        'model': {
            _id: {type: String}, 
            name: {type: String, required: true}, 
            description: {type: String}, 
            capacity: {type: Number} 
        }
    },
    {
        path: '/public/demo/ROOMS/contact',
         collection: {
                name: 'contact'
         },
        model: {
            _id: {type: String, key:"primary"}, 
            firstName: {type: String, required: true},
            lastName: {type: String, required: true},
            telephone: {type: String, required: true}, 
            fax: {type: String}, 
            email: {type: String}, 
            address: {type: String, required: true},
            postalCode: {type: String, required: true}, 
            city: {type: String, required: true},
            province: {type: String}, 
            country: {type: String}, 
            type: {type: String, required: true, enum: ['person', 'company']}
        }
    },
    {
        path: '/public/demo/ROOMS/reservation',
        collection: {
            name: 'reservation'
        },
        model: {
            _id: {type: String, key:"primary"}, 
            date: {type:Date, required:true}, 
            start: {type:Date, required:true}, 
            end: {type:Date, required:true}, 
            nbPeople: {type:Number, required:true}, 
            description: {type: String}, 
            status: {type:String, required:true, enum:['paid', 'cancelled', 'new'], default:'new'}, 
            cost: {type:Number, required:true},
            roomId: {type: String, ref: 'rooms._id'}, 
            contactId: {type: String, ref: 'contact._id'} 
        }
    },
    {
        path: '/public/demo/ROOMS/error',
        collection: {
            name: 'reservation'
        },
        model: { 
            type:{type:String, required:true, enum:['succes', 'info', 'warning', 'error', 'fail'] }, 
            title:{type:String, required:true}, 
            content:{type:String, required:true}, 
            module:{type: String},
            mailTo:{type: String}, 
            timestamp:{type:Date, required:true}, 
            context:{} 
        }
    }
])
class rooms {}
start(rooms, 'midgard_output');

Readme

Keywords

none

Package Sidebar

Install

npm i Midgard

Weekly Downloads

1

Version

0.9.7

License

GPL-3.0

Last publish

Collaborators

  • gregsavoie