Registry / web-framework / odata-v4-server

odata-v4-server

JSON →
library0.2.13jsnpmunverified

odata-v4-server is a Node.js library for building OData Version 4.0 compliant servers. It allows developers to expose OData services either as a standalone server, an Express router, or as a stream. The package facilitates defining service metadata using TypeScript decorators or a JSON schema, supporting standard OData features like query language parsing ($filter, $orderby, $top, $skip, $select, $expand, $count) and CRUD operations on entity sets. It also supports complex types, navigation properties, actions, and functions. Currently at version 0.2.13, its release cadence appears to be irregular as it's still in pre-1.0 development. A key differentiator is its extensive use of decorators for defining controllers and handling OData query parameters, streamlining the development of data services.

npm install odata-v4-server
INSTALL
IMPORT
SIG · ODATA-V4-SERVER
O
odata-v4-server
web-frameworkjavascriptv0.2.13
Install
—
Import
—
Disk
—
Pass rate
0/ 6
Env Coverage0 / 6
glibc
18–22
musl
18–22
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18–226 runs
build_error
glibc
node 18–226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

ODataServer
✓ import { ODataServer } from 'odata-v4-server';
✗ const { ODataServer } = require('odata-v4-server');
The library primarily uses ES Module syntax and TypeScript decorators. While CJS might work in some setups, ESM is the intended and idiomatic way.
ODataController
✓ import { ODataController } from 'odata-v4-server';
✗ import ODataController from 'odata-v4-server';
This is a named export. Ensure to use destructuring `{ ODataController }`.
odata
✓ import * as odata from 'odata-v4-server';
✗ import { odata } from 'odata-v4-server';
The 'odata' object contains all decorators like `@odata.GET`, `@odata.controller`, `@odata.key`. It's typically imported as a namespace.
ODataQuery
✓ import { ODataQuery } from 'odata-v4-server';
This type is used for annotating parameters that receive parsed OData query expressions, such as in `@odata.filter`.

This quickstart demonstrates how to set up a basic OData V4 server with two controllers (Products and Categories) handling standard CRUD operations, using TypeScript decorators for routing and parameter injection. It includes a minimal data store simulation and server initialization.

import { ODataController, ODataServer, odata, ODataQuery } from 'odata-v4-server'; import { MongoClient, ObjectId } from 'mongodb'; // Assuming MongoDB for example persistence // Dummy data for demonstration const products: any[] = []; const categories: any[] = []; // Helper to create a filter function (simplified for example) const createFilter = (filter: ODataQuery) => (item: any) => { // In a real application, you'd parse ODataQuery to build a robust filter predicate. // This is a placeholder. console.warn('Filter parsing in createFilter is simplified for demonstration.'); return true; }; export class ProductsController extends ODataController { @odata.GET find(@odata.filter filter: ODataQuery) { if (filter) return products.filter(createFilter(filter)); return products; } @odata.GET findOne(@odata.key key: string) { return products.find(product => product._id === key); } @odata.POST insert(@odata.body product: any) { product._id = new ObjectId().toHexString(); // Simulate MongoDB ID products.push(product); return product; } @odata.PATCH update(@odata.key key: string, @odata.body delta: any) { let product = products.find(product => product._id === key); if (product) { Object.assign(product, delta); } } @odata.DELETE remove(@odata.key key: string) { const index = products.findIndex(product => product._id === key); if (index > -1) { products.splice(index, 1); } } } export class CategoriesController extends ODataController { @odata.GET find(@odata.filter filter: ODataQuery) { if (filter) return categories.filter(createFilter(filter)); return categories; } @odata.GET findOne(@odata.key key: string) { return categories.find(category => category._id === key); } @odata.POST insert(@odata.body category: any) { category._id = new ObjectId().toHexString(); categories.push(category); return category; } @odata.PATCH update(@odata.key key: string, @odata.body delta: any) { let category = categories.find(category => category._id === key); if (category) { Object.assign(category, delta); } } @odata.DELETE remove(@odata.key key: string) { const index = categories.findIndex(category => category._id === key); if (index > -1) { categories.splice(index, 1); } } } @odata.cors @odata.controller(ProductsController, true) @odata.controller(CategoriesController, true) export class NorthwindODataServer extends ODataServer {} // Initialize some dummy data products.push({ _id: new ObjectId().toHexString(), name: 'Product A', price: 10, categoryId: 'cat1' }); categories.push({ _id: 'cat1', name: 'Category X' }); console.log('Starting OData server on port 3000 at /odata...'); NorthwindODataServer.create('/odata', 3000).then(() => { console.log('OData server started. Try accessing:'); console.log(' http://localhost:3000/odata'); console.log(' http://localhost:3000/odata/$metadata'); console.log(' http://localhost:3000/odata/Products'); console.log(' http://localhost:3000/odata/Products(\'<product_id>\')'); }).catch(err => console.error('Failed to start OData server:', err));
Debug
Known issues
gotchaThe package is still in pre-1.0 development (version 0.2.13), meaning API surface and internal implementations might change frequently with minor version bumps. Backward compatibility is not guaranteed across minor versions.
fix
Always pin to exact versions (e.g., `"odata-v4-server": "0.2.13"`) and review release notes for any update to mitigate unexpected breaking changes. Thorough testing is recommended for any upgrade.
affects: >=0.x.x
breakingThis library heavily relies on TypeScript decorators. If you are using JavaScript, you will need a transpiler (like Babel) with decorator support. For TypeScript, `"experimentalDecorators": true` and `"emitDecoratorMetadata": true` must be enabled in `tsconfig.json`.
fix
For TypeScript users, add or ensure `"experimentalDecorators": true` and `"emitDecoratorMetadata": true` are present in your `tsconfig.json`. For JavaScript users, configure Babel with the necessary decorator plugins.
affects: >=0.x.x
gotchaThe example code often uses `ObjectID` from `mongodb` or similar for key generation. When integrating with a specific database, ensure proper ID generation and persistence logic is implemented in your controller methods, replacing the dummy data logic.
fix
Replace placeholder ID generation (`new ObjectID().toString()`) with your database's actual ID generation mechanism or ORM's entity management for real-world applications.
affects: >=0.x.x
gotchaOData query parsing (e.g., for `$filter`) hands over a parsed `ODataQuery` object to the controller. Developers are responsible for implementing the logic to translate this parsed query into database queries or filtering operations. The example provides only a simplified placeholder.
fix
Thoroughly implement the `createFilter` (or similar) function to correctly interpret the `ODataQuery` object and apply it to your data source (e.g., SQL queries, NoSQL queries, in-memory filtering).
affects: >=0.x.x
Errors
Common errors & fixes
ReferenceError: Reflect is not defined
Missing `reflect-metadata` polyfill or incorrect `tsconfig.json` settings for decorators.
fix
Install `reflect-metadata` (`npm i reflect-metadata`) and import it once at the entry point of your application (`import 'reflect-metadata';`). Also, ensure `"emitDecoratorMetadata": true` is set in `tsconfig.json`.
error TS2307: Cannot find module 'odata-v4-server' or its corresponding type declarations.
Package not installed, or TypeScript cannot find its declaration files.
fix
Ensure `odata-v4-server` is installed (`npm i odata-v4-server`). If using an older TypeScript version or complex project setup, verify `node_modules/@types/odata-v4-server` (if it existed) or `node_modules/odata-v4-server/dist/index.d.ts` is correctly resolved by your `tsconfig.json`.
Error: Decorators are not enabled. You must enable them in your TypeScript configuration (experimentalDecorators: true).
`experimentalDecorators` is not enabled in `tsconfig.json`.
fix
Add `"experimentalDecorators": true` to the `"compilerOptions"` section of your `tsconfig.json`.
TypeError: Cannot read properties of undefined (reading 'create')
Trying to call `ODataServer.create` without ensuring `NorthwindODataServer` extends `ODataServer` and is correctly decorated, or a transpilation issue.
fix
Verify that your server class properly `extends ODataServer` and that all decorators (`@odata.controller`, `@odata.cors`) are applied and transpiled correctly. Ensure `reflect-metadata` is imported at the top of your entry file.
Upgrade
Version history
0.2.13latest on npm
Audit
Dependencies
odata-v4-parserrequiredRequired for parsing OData query language expressions like $filter and $orderby.
odata-v4-service-metadataoptionalNeeded if setting up metadata via JSON instead of decorators.
Agent activity
9 hits · last 30 days
node
8
Resources
odata-v4-server — npm install odata-v4-server · libregistry