pofider / node-simple-odata-server

Simple OData server for node.js
MIT License
97 stars 60 forks source link

Update odataServer.js - add /:collection/\$metadata route #20

Closed tuan2174 closed 7 years ago

tuan2174 commented 7 years ago

Added additional /:collection/\$metadata route so the root path is not used by simple-data-server. I need the server to return a nicely formatted http error (not in odata format) when a client sends an incorrect url. I don't want odata to handle root path.

pofider commented 7 years ago

I'm not sure if I understand. You mentioned you don't want odata to handle the root path. In the following case odata should handle only /odata* for example.

app.use("/odata", function (req, res) {
        odataServer.handle(req, res);
    });

I was not able to find the path /:collection/$metadata in odata spec. Is it actually valid?

tuan2174 commented 7 years ago

Thank you for feedback. In my case, I would need odata to handle this path structure:http://localhost:3000/odata/*http://localhost:3000/odata/$metadata

app.use("/odata", function (req, res) {         odataServer.handle(req, res);     }); Before the change, it expects $metadata to be in http://localhost:3000/$metadata I looked up this and am trying to find out more about metadata and where it should be defined and with no luck- http://www.odata.org/documentation/odata-version-2-0/overview/

Thank you

  From: Jan Blaha <notifications@github.com>

To: pofider/node-simple-odata-server node-simple-odata-server@noreply.github.com Cc: tuan2174 tuan2174@yahoo.com; Author author@noreply.github.com Sent: Tuesday, November 1, 2016 1:45 AM Subject: Re: [pofider/node-simple-odata-server] Update odataServer.js - add /:collection/\$metadata route (#20)

I'm not sure if I understand. You mentioned you don't want odata to handle the root path. In the following case odata should handle only /odata* for example.app.use("/odata", function (req, res) { odataServer.handle(req, res); });I was not able to find the path /:collection/$metadata in odata spec. Is it actually valid?— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

pofider commented 7 years ago

I thought odata metada should be defined on /$metadata on odata endpoint root and that is it. I'm hesitating to merge something what is not part of the standard.

app.use("/odata", function (req, res) {
        odataServer.handle(req, res);
    });

should serve metadata on /odata/$metadata. If it doesn't , it is wrong.

tuan2174 commented 7 years ago

It doesnt. That is why I made a change to allow it to handle /odata/$metadata. After change, it works. Thanks

pofider commented 7 years ago

I've tried and it does for me. Look at this simple web app. It is correctly serving metadata on odata/$metadata . Am I missing something?

var http = require('http');
var Datastore = require('nedb');
var db = new Datastore( { inMemoryOnly: true });
var ODataServer = require("simple-odata-server");

var model = {
    namespace: "jsreport",
    entityTypes: {
        "UserType": {
            "_id": {"type": "Edm.String", key: true},
            "test": {"type": "Edm.String"},            
        }
    },   
    entitySets: {
        "users": {
            entityType: "jsreport.UserType"
        }
    }
};

var express = require('express')
var app = express()

var odataServer = ODataServer()
    .model(model)
    .onNeDB(function(es, cb) { cb(null, db)});

app.get('/', function (req, res) {
  res.send('Hello World!')
})

app.use("/odata", function (req, res) {
        odataServer.handle(req, res);
    });

app.listen(3000)
tuan2174 commented 7 years ago

Thank you for providing an example! The code does work. I can see a good response with this URL http://localhost:3000/odata/$metadata. After some digging, the difference is how odataserver is initiated. In my code, I have - var odataServer = ODataServer('http://soa.api.company.com') I got namespace 'http://soa.api.company.com' in my code. If I leave it blank, $metadata works but http://localhost:3000/customers will not return data from db (mongodb client in my case). Instead it shows something like this - {"@odata.context":"http://localhost:3000/customers/$metadata","value":[{"kind":"EntitySet","name":"providers","url":"providers"}]}

pofider commented 7 years ago

If I leave it blank, $metadata works but http://localhost:3000/customers will not return data from db (mongodb client in my case).

Shouldn't that be http://localhost:3000/odata/customers ?

tuan2174 commented 7 years ago

Ok I see where the problem is in my code. Odata expects \odata (or something called "prefix" used in router). After {prefix}, it expects /:collection to return all data. I will close this thread. Thanks!