@randajan/odata-server

2.1.16 • Public • Published

Node odata-server

NPM Version License

Simple implementation of OData server running on Node.js with easy adapters for mongodb Just define an OData model, provide a mongo, hook into node.js http server and run.

It supports basic operations you would expect like providing $metadata, filtering and also operations for insert, update and delete. On the other hand it suppose to be really simple so you don't get support for entity links, batch operations, atom feeds and many others.

Get started

This is how you can create an OData server with node.js http module and mongodb.

import ODataServer from "@randajan/odata-server";
import mongoAdapter from "@randajan/odata-server/mongoAdapter";

import { MongoClient } from "mongodb";
import http from "http";

const mongo = {
    url:"mongodb://localhost:27017",
}

const getMongo = async context=>{

    if (!mongo.current) { 
        mongo.current = await MongoClient.connect(mongo.url);
        mongo.current.on("close", _=>{ delete mongo.current; });
        process.on("exit", _=>{
            if (mongo.current) { mongo.current.close(); }
        });
    }
    
    return mongo.current;
}

const config = {
    url:'http://localhost:1337',
    cors:"*",
    model:{
        namespace: "main",
        entityTypes: {
            "UserType": {
                "_id": {"type": "Edm.String", key: true},
                "test": {"type": "Edm.String"},            
            }
        },   
        entitySets: {
            "users": {
                entityType: "main.UserType"
            }
        }
    },
    adapter:mongoAdapter(getMongo),
    extender:(context, customServeArgument)=>{
        context.customProperty = customServeArgument;
    }
    converter:(primitive, value, method)=>{
        console.log(primitive, value, method);
        return value;
    },
    filter:(context, collectionName, propertyName)=>{
        console.log(context.customProperty, collectionName, propertyName);
        return true;
    },
}

const server = ODataServer(config);

http.createServer(server.serve("http://localhost:1337", "This will be present at 'context.customProperty'")).listen(1337);

Now you can try requests like:
GET http://localhost:1337/$metadata
GET http://localhost:1337/users?$filter=test eq 'a' or test eq 'b'&$skip=1&$take=5
GET http://localhost:1337/users('aaaa')
GET http://localhost:1337/users?$orderby=test desc
GET http://localhost:1337/users/$count
POST, PATCH, DELETE

server.serve(responder, url, ...extendArgs)

This is factory function and will return resolver binded to the server. The first argument represent base url. Next arguments will be passed to the function extender.

responder

There is only two implementation for now

  • express - @randajan/odata-server/express
  • koa - @randajan/odata-server/koa

You can create your own responder. It accepts function that will create object with these properties:

  • getURL
  • getMethod
  • getBody (could be async)
  • getType (json || xml) affect only $metadata
  • setHeader
  • setBody

config property

config.adapter

There is currently single adapter implemented.

  • mongodb - @randajan/odata-server/mongo

You can create your own adapter. It accepts any kind of object and it will look for certain properties:

  • get
  • count
  • insert
  • update
  • remove

config.cors

You can quickly set up cors without using express and middlewares using this property

config.converter

You can define your custom type converter. It will be called everytime property tries to convert value to primitive type. List of primitive types:

  • Edm.Int16
  • Edm.Int32
  • Edm.Int64
  • Edm.Boolean
  • Edm.String
  • Edm.Date
  • Edm.Single
  • Edm.Double
  • Edm.Decimal
  • Edm.TimeOfDay
  • Edm.DateTimeOffset
  • Edm.Byte
  • Edm.SByte3
  • Edm.Binary

There is two possible ways to create custom converter:

  1. As function: const converter = (primitive, value, method)=>{ ... }
  2. As object: const converter = { [primitive]:(value, method)=>{ ... } }

Argument method represent the direction of conversion and it could be one of:

  1. "toAdapter": it represent the value coming from the request
  2. "toResponse": it represent value coming from the adapter

config.filter

Provide function here for dynamic filtering model (entities and their props). Everytime server tries to access model it will call this function. Return false means that there is no access. This can't be used to filter records based on their value.

config.extender

This function will be called everytime context is created so you can add your own properties and pass them to the adapter. First argument will be context, and next arguments will be anything passed to the odataServer.serve function

Limitations

  • no entity links
  • no batch operations
  • no validations
  • ... this would be a very long list, so rather check yourself

Credits

The initial version of this project was created by pofider and can be found at https://github.com/pofider/node-simple-odata-server.

License

See license

Package Sidebar

Install

npm i @randajan/odata-server

Weekly Downloads

0

Version

2.1.16

License

MIT

Unpacked Size

107 kB

Total Files

15

Last publish

Collaborators

  • randajan