Search code examples
odatajaydataolingo

ODATA javascript client libraries (what is their value over simple Fetch or AJAX)?


Currently we are using client-side javascript fetch to connect to our ODATA V4 ERP server:

const BaseURL = 'https://pwsepicorapp.com/ERP10.2/api/v1/Erp.BO.JobEntrySvc/'

const fetchJobNum = (async () => {
    let url = BaseURL + 'GetNextJobNum'
    const reply = await fetch(url,{
        method: 'POST',
        mode: 'cors',
        headers: {
            'Accept': 'application/json',
            'Authorization': 'Basic xxxx',
            'x-api-key' : '0HXJZgldKZjKIXNgIycD4c4DPqSrzn2UFCPHbiR1aY7IW',
            'Access-Control-Allow-Origin': '*',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({})
    })
    let rsp = await reply.json()
    let job = rsp.parameters.opNextJobNum
    return job
})

And this works fine for us. We recently started looking at javascript ODATA libraries (Apache OLINGO, O.js, JayData (or other ones suggested at: https://www.odata.org/libraries/)

But what I don't see is an objective guide for a developer understand why and what these libraries provide.

I.e. I think they read the meta-data for the particular ODATA service. Fine but what does power does that add?

Perhaps my mental block is that we are only:

  1. searching only JSON data
  2. Not doing any nested queries (only simple $filter, $select)
  3. Just doing simple GET, POST, PATCH
  4. Or perhaps these libraries were needed for functionality that was missing before ODATA V4

Can anyone give a succinct description of the features for these libraries and their UNIQUE VALUE PROPOSITIONS (to borrow a Venture Capital Term) to developers? I bet others would find this useful.


Solution

  • Short Answer

    You are right. If all you are doing just the simple operations you don't need any of these libraries as at the end of the day they are just REST calls that follow some specific conventions(i.e. OData specification).

    Long Answer

    The reason we have all these client side APIs is that OData offers/defines a lot more stuff.

    Lets try to go though it with an example. The example I am using is Batch Requests in OData. I simplest of the terms Olingo defines a way to club multiple HTTP requests in one. It has a well defined syntax for it. That looks something like this

    POST /service/$batch HTTP/1.1 
    Host: host 
    OData-Version: 4.0
    Content-Type: multipart/mixed; boundary=batch_36522ad7-fc75-4b56-8c71-56071383e77b
    Content-Length: ###
    
    --batch_36522ad7-fc75-4b56-8c71-56071383e77b
    Content-Type: application/http 
    
    GET /service/Customers('ALFKI') 
    Host: host
    
    --batch_36522ad7-fc75-4b56-8c71-56071383e77b 
    Content-Type: application/http 
    
    GET /service/Products HTTP/1.1 
    Host: host 
    
    --batch_36522ad7-fc75-4b56-8c71-56071383e77b--
    

    Now there are quite a few things here.

    • You have to start the batch request with batch_<Unique identifier> and separate individual HTTP requests with the batch boundary, and when you are done you end it with batch__<Unique identifier>--
    • You set the batch identifier in as the header and send additional headers(like content-type, content-length) properly that you can see in the .

    Now coming back to your original question sure you can use a lot of string concatenation in your JavaScript code and generate the right payload and make an ajax call then parse back a similar kind of response, but as an application developer all you care about is batching your GET, POST, PUT and DELETE request and operation the operation you desire.

    Now if you use a client library(the example is generic and might differ from library to library) the code should look something like

    OData.request( {
        requestUri: "http://ODataServer/Myservice.svc/$batch",
        method: "POST",
        data: { __batchRequests: [
           { requestUri: "Customers('ALFKI')", method: "GET" },
           { requestUri: "Products", method: "GET" }
        ]}
    },
    function (data, response) {
        //success handler
    }, undefined, OData.batchHandler);
    

    So on a purely business proposition terms libraries like these can save you quite a few man hours based on your application size that will be consumed on generating the right payload strings or right URL string(in case of filters, navigation properties etc.) and debugging thought the code in case you missed a bracket or misspelled a header name, which can be used on building the core logic for the application/product and let the standardized, repetitive and boring(opinionated thought) work for you.