OData NxT - The Future of OData (Project Proposal) #6
Replies: 36 comments 3 replies
-
I will be setting up public design discussions and we will share the progress on this new initiative with everyone soon. |
Beta Was this translation helpful? Give feedback.
-
Thanks Hassan for initiating this.
Need to watch the whole video but the pieces I saw are already impressive. Can you please elaborate in which way
Can you give some examples for extensions you have in mind. The next version already makes some progress how it plugs in into the ASP.NET pipeline (middleware/routing) and also how EDM and model builders are factored. Is this sufficient or are you thinking about even more granular modules ?
OData is couple to HTTP in many ways. ODL is a .NET implementation and the quasi web service implementation standard for this is ASP.NET, I am not sure what technology you would want to swap in this stack. How would a hypothetical ODATA over gRPC look like? Not saying it is not imaginable but I don't see this at the moment. Maybe this is something that is in line with your thinking here and I am wondering about sometimes. ODL very much expects that types implementing IQueryable are returned. This means the flow is: |
Beta Was this translation helpful? Give feedback.
-
Hi @chrisspre For transcendence About the modularity here's some thoughts. As for the decoupling from ASP.NET or any other protocol. My thought process here is to allow OData to be configurable to support multiple communication protocols. Assume that I have an input parameter in a simple console application that reads files from a system. Now, imagine that the console is offering an What do you think? |
Beta Was this translation helpful? Give feedback.
-
Here's our very first session: Some actionable items to update this thread with:
|
Beta Was this translation helpful? Give feedback.
-
@xuzhg and I had a great session diving into the details of AST and Expression Trees in the current implementation of OData - watch it here: |
Beta Was this translation helpful? Give feedback.
-
The "Transcendence"/ Transference? I watched your video architecture discussion. It seems to me with the diagram you were showing an API Gateway (?) fronting the Odata microservice. Seems to me need aggregation/slicing to 1..N Odata services, abstracting those away with your LINQ ideas. This would lead to something like GraphQL concept of joining data sources applied to Odata. That seems like would a strong position to be in. bad example just grabbed after search: https://hasura.io/blog/remote-joins-a-graphql-api-to-join-database-and-other-data-sources/ |
Beta Was this translation helpful? Give feedback.
-
As an F# developer using giraffe instead of classic ASP.NET web api, routing dependence is one of the setbacks for me. I'd highly appreciate a more agnostic approach. |
Beta Was this translation helpful? Give feedback.
-
My initial thoughts on this proposal ... Surely the trick here is to implement a LINQToOData provider so that a local "generated proxy". That would give you a strongly typed client side OData context that you execute a LINQ query on essentially gets translated to an OData question to give you back an IQueryable Pseudocode idea ... // how WCF would do it
var proxy = new MyODataClient("https://.../swagger/v1.swagger.json");
var result = proxy.GetAll<City>().Where(c => c.Name == "Redmond").ToArray();
// smarter ligthweight method ...
var proxy = new ODataQueryable<City>("https://localhost/");
var result = proxy.GetAll<City>().Where(c => c.Name == "Redmond").ToArray(); The above issues a HTTP GET to ~/City?$filter=Name eq 'redmond' on the API. For server side implementation surely that RESTFulLinqService class used in the video could be implemented as an optional middleware so that consumers can just call ... app.useLinqQuerying(); Then in our controllers we can do something like ... public IActionResult Get(ILinqOptions opts) => Ok(opts.ApplyTo(Db.Set<T>()); ... this then brings it inline with how Odata options work too. I'm assuming most people implement their API's like I do and separate their entity types from their business logic, so having a simple lightweight "DTO dll" would serve this approach well. I'm also assuming that really all that's going on here is what takes place in DynamicLinq mapped form the URL. |
Beta Was this translation helpful? Give feedback.
-
PLEASE coordinate with the API Versioning and Swagger/Swashbuckle/OpenAPI teams in any upcoming releases. |
Beta Was this translation helpful? Give feedback.
-
I'm not certain how this is different than ODataQueryOptions. I feel like Linq just opens up all options rather than allowing the developer to restrict to what they want permitted. |
Beta Was this translation helpful? Give feedback.
-
Quick update from our last session with @xuzhg In this video, Sam and I will show you how to take in a raw #OData query in a simple console application and convert it into Abstract Search Tree. This video is a part of a series to revolutionize OData to make it a technology agnostic technology with capabilities such as transcendence, modularization and pluggability into any communication protocol. |
Beta Was this translation helpful? Give feedback.
-
Would be great to see OData playing nicely with GraphQL. Not just for queries, but also subscriptions. |
Beta Was this translation helpful? Give feedback.
-
GraphQL baffles me ... technically it's ok to have a body in a HTTP GET according to the standard but i've not seen it until GraphQL. @hassanhabib Would be cool to see how OData works with say ... multiple sets of IEnumerable and then using the model figures out how to stitch things together such that we don't require IQueryables (causing a leaky abstraction of functionality in things like EF to be required to be pulled all the way through to our API layers. Another neat feature would be to be able to take an OData querystring and apply it to an IEnumerable to build an expression tree as it's own smaller lib without a model requirement for those using things like Swagger that don't want to build OData models and just want to use MVC and allow for OData querying in their own controller code. This may also be a smarter way to rebuild the code in the EnableQuery attribute which is insanely deep in call tree depth. |
Beta Was this translation helpful? Give feedback.
-
In this session, Sam and I will show you how to convert a raw OData query into an IQueryable then to a List. |
Beta Was this translation helpful? Give feedback.
-
@hassanhabib The act of dealing with an OData string should be straight forward through just raw dynamic LINQ "within the OData expression scope". My thinking is as follows. What if we could do something like this ... var i = new List<T>();
var results = i.ODataApply("?$filter=Value gt 123&$select=x,y,z"); <-- composition of OData on top of a list My issue with your approach is this need for all this declaration of metadata and the OData model before simply building what amounts to an expression tree composed over an IEnumerable Thinking it more "generally speaking" OData queries are basically a small subset of what is already doable using Dynamic LINQ. Why do we need the OData model at all other than to define T which in this context we already have? .... The other "useful scenario" here is where I do the above then do something like ... var results = await new HttpClient(new Uri("base url")).GetAsync(results.ToOdataString()); <-- the reverse from the server ... to retrieve the items from the server that relate to the constructed client side expression tree. It's this simplicity that matters to consumers of the OData api's, the OData model is really more important for determining what you're interacting with (like getting the definition of T as XML / json). In my opinion as a consumer anything more than this is the result of over complexity in the OData API. One thing that might be helpful though if an Odata model is needed would be a "model from" type thing like this ... var modelTypeSet = new Type[] { typeof(someType), typeof(SomeType2), typeof(someType3) ... };
ODataModel model = modelTypeSet.BuildODataModel(); This reduces a ton of overhead on the consumer and builds out the model entirely in framework code "correctly" so if these conventions / the implementation needs to change for some reason this can be altered completely within the framework. By Extension we could then do something like this in our Api applications on the Server Side ... var controllerArray = AppDomain.Current.GetAssmeblies()
.SelectMany(a => a.GetExportedTypes())
.where(t => t.HasAttribute(ODataController);
MethodInfo[] missingImplementations;
if(!model.IsFullyImplementedBy(controllerArray, out missingImplementations))
{
throw ODataNotImplementedException(missingImplementations);
} This focus on having us as consumers build the model is generally not the thing we care about, as much as it would help to be able to manipulate the model, actually building one can be done automatically through reflection IMO and so needs to be moved internally in to the framework. |
Beta Was this translation helpful? Give feedback.
-
@TehWardy my apologies for the delay. Just working through some scheduling and planning issues for the project. We are still here and active - a new video in the series coming out next week Friday. |
Beta Was this translation helpful? Give feedback.
-
Hi everyone, I’ve also recently implemented In case that someone is not familiar with the purpose if this interface, then it can be compared to Edit: I added the following table to visually depict the above mentioned abstractions:
It is alright in my opinion to use my library let`s say in a server side Blazor application or in a microservice. But on the other hand I'm convinced that the message broker shouldn't be exposed in the same way as databases aren’t. They are usually hidden behind a (micro) web service. So I’ve recently again started to think about using OData queries as an intermediary between servers and clients (UIs), and I found this great proposal of yours. What do you think about my thoughts? Let me know in case that I can help you somehow with your tremendous effort. |
Beta Was this translation helpful? Give feedback.
-
@tomasfabian I love this idea. This is essentially the transcendence aspect of this effort. I'm going to publish a roadmap for OData next week and maybe we can incorporate your ideas and make something bigger than the both of us :) |
Beta Was this translation helpful? Give feedback.
-
Loving this! I figured the general idea here is to do something Kendo UI does with it's OData data source but with observables over SignalR ... ... essentially combining the functions of both. I think the biggest hurdle here is making all that integration work as intended and remain "dev friendly". Weirdly i'm on the same page here and looking to solve similar problems of data being updated perhaps by automation or a user action elsewhere and keeping the data your currently looking at up to date in real time. The idea I had was to have the act of EF seeing a CRUD operation take place (through it's change tracker) on a given entity that the user has access to "trigger" an event that pushed a notif like "entity of type with primary key has been updated" that would then allow the observable to request that back from the API. I had the same idea behind this where I coined Taking the approach described by @tomasfabian would integrate all that, my only reservation is the complexity involved in all the moving parts ... perhaps a vision that has the parts exposed such that we as consumers can plug in and remove as needed rather than having a library that abstracts all the complexity behind this from us. My thinking here being ... when it doesn't behave, getting tickets resolved will be tough! Based on past experiences ... Look at how much we already have to build out to prove an issue in EF (they often ask for an entire repo with a repro project in it to explain the problem) ... this is going to be orders of magnitude more complex to debug. with something like Kendo (as linked above though) you can often get away with just posting your grid init code block. |
Beta Was this translation helpful? Give feedback.
-
@TehWardy I totally agree with you. We are trying to solve similar/same problems individually, such as refreshing UIs based on CRUD operations. For sure it will increase the complexity of our systems, that we will have to deal with. It will introduce new challenges to us as you mentioned, such as good traceability, observability etc.
I also wrote a package for SqlServer's Change data capture, so you can actually even limit, filter out row-level table notifications server-side with ksqldb (I didn't see this option in the kendo example you provided us), replicate the redo logs, and so on. My whole idea was to take advantage of the stream-table duality for CRUD operations. The downside is that you have to manage Kafka brokers, ksqldb, Kafka Connect, possibly even Kubernetes since this is a highly scalable, fault tolerant distributed approach. So what I would love to achieve, is to bring these possibilities also to the UI clients with the help of OData.NxT, because at the moment it is only safe to use it with internal server-side consumers. The ideal would be to initially load some (paged) data and subscribe to only the relevant change notifications. @hassanhabib I'm looking forward for a potential cooperation. Let's go further with our common (community) dream: LINQ TO EVERYTHING! |
Beta Was this translation helpful? Give feedback.
-
@tomasfabian I'm curious ... In short: Adding a standardised subscription mechanism in to the API layer should be enough to trigger clients in to pulling the changes after an operation is actioned. ... so my thinking is ... huh, why get the db involved here? I only say this as I think the real magic in all this work @hassanhabib is doing is that we would end up with the pieces and thus more flexibility if done right rather than a bigger more monolithic separation of concerns issue. |
Beta Was this translation helpful? Give feedback.
-
@TehWardy @hassanhabib's proposal is 100% correct and GREAT and I don't have any objections against it. I was just presenting its usage with Simply put IKSqlQueryProvider does the same as usual ORM's do, but in this case the data is pushed to the clients, not pulled by clients. It handles your KSQL interactions. The stream processing database is necessary to do some kind of stream processing server side, it’s not mandatory. As an example you can create a push query that joins 2 or more tables/streams, projects the data, filters it and emit only the appropriate not filtered out, enriched messages to the subscriber(s). These queries are potentially endless and they continuously notify your consumers about updates or new data based on your LINQ query. |
Beta Was this translation helpful? Give feedback.
-
@tomasfabian Ah ok ... I've been bolting on my own eventing model on top of EF such that entities in the change tracker when a save changes call takes place are fed in to a custom event raiser, my thinking was that I could do things like execute a workflow or drop a notification (or the entity) on to a signalr hub for subscribers to pick up. I hadn't considered writing my own ORM lol! |
Beta Was this translation helpful? Give feedback.
-
Updating this thread with our game plan (roadmap) for OData NxT. We are moving the party over to this repo: |
Beta Was this translation helpful? Give feedback.
-
Nice ... thank you for keeping us in the loop :) |
Beta Was this translation helpful? Give feedback.
-
@xuzhg , @hassanhabib and @tomasfabian, Can we borrow the concept of Modular Fluent API Configuration from https://github.com/Biarity/Sieve? |
Beta Was this translation helpful? Give feedback.
-
You mean borrow it from Entity Framework, AutoMapper, or most IoC containers? It is not a new concept and definitely not introduced by that fairly new and unknown library. |
Beta Was this translation helpful? Give feedback.
-
Hey guys, I created a Discord community for OData Neo here: |
Beta Was this translation helpful? Give feedback.
-
@hassanhabib all, I just converted the issue as a discussion. Thanks. |
Beta Was this translation helpful? Give feedback.
-
Is it possible to use OData with Minimal API only, ie without controllers? |
Beta Was this translation helpful? Give feedback.
-
Here's some thoughts for OData NxT
Transcendence- We need to be able to provide transient queries. meaning that if I want to relay my OData queries from one API to the next it should be easy to communicate that through some sort of protocol. I have an proposal for IQueryableAsync .NET implementation while still conforming to OData protocols.
Modularization - we need to allow people to build extensions and modules to add new extensions - If I want to create an extension to provide some new functionality then they should be able to create the extension and offer the new functionality.
Technology-Agnostic from ASP.NET routing. We need to reconceptualize our OData implementation so it's not tightly coupled to a certain implementation for ASP.NET - we want that concept to allow other protocols like gPRC for instance to allow.
The most important part about all of this is to allow our framework to be extensible, agnostic and modular. I will follow up with more details about this initiative soon.
Beta Was this translation helpful? Give feedback.
All reactions