Git Product home page Git Product logo

yang-express's Introduction

yang-express

YANG model-driven Express framework

Minimalistic web framework leveraging powerful YANG schema expressions according to RFC 6020. Generates dynamic model-driven interfaces with flexible plugin system.

NPM Version NPM Downloads

Installation

$ npm install -g yang-express

The preferred installation is global for easy access to the yang-express utility but can also be used as a dependency module to enable YANG model-driven express app as part of your project.

For development/testing, clone from repo and initialize:

$ git clone https://github.com/corenova/yang-express
$ cd yang-express
$ npm install

Features

  • Robust model-driven routing
  • Hotplug runtime models
  • Dynamic interface generators
  • Hierarchical (deeply nested) data tree
  • Adaptive validations
  • Flexibe RPCs and notifications

Quick Start

$ yang-express example/example-petstore.yang

The above example will import the example-petstore YANG module and start an instance of yang-express listening on port 5000 with restjson feature enabled.

  Usage: yang-express [options] modules...

  Options:
      -p, --port <number>    Run yang-express on <port> (default: 5000)
      -f, --feature <name>   Enable one or more features: (restjson, openapi, etc.)

You can run yang-express inside your own project and it will dynamically import one or more modules and route them using the feature plugins specified.

You can also use it as a library module:

require 'yang-js'
opts =
  port: 5000
  feature: [ 'restjson', 'openapi' ]
  modules: [ 'ietf-yang-library' ]
express = require('yang-express').eval()
express.in('run')
  .invoke opts
  .then  (res) -> console.log "running"
  .catch (err) -> console.error err

For more information on programmatic usage, be sure to take a look at the References listed below.

References

This module is a YANG model-driven data module, which is essentially a composition of the YANG Schema and Control Binding. It is designed to model middleware routing runtime configuration and can be utilized with or without an actual Express instance.

Examples

PetStore is a simple example based on the provided spec sample in the OpenAPI Specification 2.0 project.

$ npm run example:petstore

When the yang-express app runs, it will auto-generate the data model using the example-petstore.yang schema and dynamically route the following endpoints utilizing the restjson dynamic interface generator:

endpoint methods description
/pet CRUMDO operate on the pet collection
/pet/:id RUMDO operate on a specific pet
/pet/:id/:leaf RUMDO operate on a pet's attribute
/pet/:leaf RUMDO bulk operate attributes*

This example runs using the sample data found inside the config directory.

CRUMDO

  • C: CREATE (POST)
  • R: READ (GET)
  • U: UPDATE (PUT)
  • M: MODIFY (PATCH)
  • D: DELETE
  • O: OPTIONS

Alternative API endpoints can be fully-qualified /petstore:pet/... as well as prefix-qualified /ps:pet/.... This is the suggested convention when using multiple models that may have namespace conflict (if mounted together at '/').

Note: Bulk operation on all matching attributes can be used to set a new value for every matching attribute in the collection.

Dynamic Interface Generators

name description
restjson REST/JSON API
openapi OpenAPI/Swagger 2.0 spec
websocket socket.io

Tests

To run the test suite, first install the dependencies, then run npm test:

$ npm install
$ npm test

License

Apache 2.0

This software is brought to you by Corenova Technologies. We'd love to hear your feedback. Please feel free to reach me at [email protected] anytime with questions, suggestions, etc.

yang-express's People

Contributors

ramukima avatar sekur avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

yang-express's Issues

yangapi: GET broken

bash-4.3$ curl localhost:5000/petstore.yang
{
  "error": {
    "message": "Cannot read property 'length' of undefined"
  }
}
TypeError: Cannot read property 'length' of undefined
  at ......./yang-express/lib/yangapi.js:16:32

openapi: Cannot read property 'nodes' of undefined

Understand that this is still under development. I am reporting this for tracking -

Running the yang-express/example petstore, I get the following error -

bash-4.3$ curl localhost:5000/openapi.spec
{
  "error": {
    "message": "Cannot read property 'nodes' of undefined"
  }
}bash-4.3$

Server Log -

TypeError: Cannot read property 'nodes' of undefined
  at Function.restjson.paths (.../yang-express/lib/restjson.js:138:18)
  at .../yang-express/lib/openapi.js:57:27

I am using following versions of dependencies :
"yang-express": "^0.3.9",
"yang-js": "^0.15.16",

The latest changes to yang-js project may have broken it.

TypeError: discover is not a function

if you run " git clone https://github.com/corenova/yang-express;" then run "cd yang-express" then run "npm install"

and finally you run "yang-express example/example-petstore.yang" or "npm run example:petstore"

you get this error message:

[email protected] example:petstore /home/bay/workspace/tmp/yang-express
NODE_ENV=example NODE_APP_INSTANCE=petstore bin/yang-express --router restjson example-petstore

TypeError: discover is not a function
at Method.rpc(listen) (/home/bay/workspace/tmp/yang-express/yang-web-store.js:36:13)
at Method.do (/home/bay/workspace/tmp/yang-express/node_modules/yang-js/lib/method.js:42:64)
at Object. (/home/bay/workspace/tmp/yang-express/bin/yang-express:45:27)
at Module._compile (internal/modules/cjs/loader.js:1076:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
at Module.load (internal/modules/cjs/loader.js:941:32)
at Function.Module._load (internal/modules/cjs/loader.js:782:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
at internal/main/run_main_module.js:17:47

Strange POST behavior on nested lists

Notice the strange behavior on nested list structure...

Yang Model

bash-4.3$ cat example/petstore.yang
module petstore {
  prefix ps;
  description "Yang Petstore";
  grouping Pet {
    leaf id   { type uint64; mandatory true; }
    leaf name { type string; mandatory true; }
    leaf tag  { type string; }
  }
  list pet {
    key "id";
    uses Pet;

    list childpet {
      key "id";
      uses Pet;

      list grandchildpet {
        key "id";
        uses Pet;
      }
    }
  }
}
bash-4.3$

Seed Data

bash-4.3$ cat example/petstore.json
{
  "petstore:pet": [
    {
      "id": "1",
      "name": "happy",
      "tag": "friendly"
    },
    {
      "id": "2",
      "name": "boba",
      "tag": "hyper"
    }
   ]
}
bash-4.3$

Add a childpet to pet-1 (FAILS)

bash-4.3$ curl -i -X POST localhost:5000/pet/1/childpet -H 'content-type: application/json' -d '{ "id": 2, "name": "childpet-1", "tag": "test" }'
HTTP/1.1 400 Bad Request
X-Powered-By: Express
Date: Wed, 17 Aug 2016 21:27:09 GMT
Connection: keep-alive
Content-Length: 0

Seed Data

bash-4.3$ cat example/petstore.json
{
  "petstore:pet": [
    {
      "id": "1",
      "name": "happy",
      "tag": "friendly",
      "childpet": [
         {
           "id": 1,
           "name": "childpet-1"
         }
      ]
    }
   ]
}

Add a childpet to pet-1 (FAILS)

bash-4.3$ curl -i -X POST localhost:5000/pet/1/childpet -H 'content-type: application/json' -d '{ "id": 2, "name": "childpet-2", "tag": "test" }'
HTTP/1.1 400 Bad Request
X-Powered-By: Express
Date: Wed, 17 Aug 2016 21:30:32 GMT
Connection: keep-alive
Content-Length: 0

bash-4.3$

Seed Data

bash-4.3$ cat example/petstore.json
{
  "petstore:pet": [
    {
      "id": "1",
      "name": "happy",
      "tag": "friendly",
      "childpet": [
         {
           "id": 1,
           "name": "childpet-1"
         },
         {
           "id": 2,
           "name": "childpet-2"
         }
      ]
    }
   ]
}
bash-4.3$

Add childpet to pet-1 (PASS)

bash-4.3$curl -i -X POST localhost:5000/pet/1/childpet -H 'content-type: application/json' -d '{ "id": 3, "name": "childpet-3", "tag": "test" }'
HTTP/1.1 201 Created
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 98
ETag: W/"62-mejvL9nQf9lcsyqhkXHBMw"
Date: Wed, 17 Aug 2016 21:31:52 GMT
Connection: keep-alive

{
  "childpet": [
    {
      "id": 3,
      "name": "childpet-3",
      "tag": "test"
    }
  ]
}bash-4.3$

Add another pet (PASS)

bash-4.3$ curl -i -X POST localhost:5000/pet -H 'content-type: application/json' -d '{ "id": 2, "name": "pet-2", "tag": "test" }'
HTTP/1.1 201 Created
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 97
ETag: W/"61-9M3Baw4B9J+SWeUkwC8qpw"
Date: Wed, 17 Aug 2016 21:35:51 GMT
Connection: keep-alive

{
  "petstore:pet": [
    {
      "id": 2,
      "name": "pet-2",
      "tag": "test"
    }
  ]
}

Add a childpet to newly added pet-2 (FAILS)

bash-4.3$ curl -i -X POST localhost:5000/pet/2/childpet -H 'content-type: application/json' -d '{ "id": 1, "name": "childpet-1", "tag": "test" }'
HTTP/1.1 400 Bad Request
X-Powered-By: Express
Date: Wed, 17 Aug 2016 21:35:24 GMT
Connection: keep-alive
Content-Length: 0

bash-4.3$

Facing errors while trying to run yang-express

Hi There,

I was trying to integrate a yang-parser in an Angular (v9) application, for which I resorted to using yang-express. After installing I ran below command:

yang-express src/app/yangs/demo.yang 

It yields below output, the issue it's pointing to is in the yang-express file inside the bin folder.

WARNING: No configurations found in configuration directory:/home/yang-demo/config
WARNING: To disable this warning set SUPPRESS_NO_CONFIG_WARNING in the environment.
/usr/local/lib/node_modules/yang-express/bin/yang-express:37
var schema = require('..').bind({
                           ^

TypeError: require(...).bind is not a function
    at Object.<anonymous> (/usr/local/lib/node_modules/yang-express/bin/yang-express:37:28)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)

I am running node version 10.19.0 and npm 6.14.4.
Please provide your thoughts.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.