OData / odata.net

ODataLib: Open Data Protocol - .NET Libraries and Frameworks
https://docs.microsoft.com/odata
Other
686 stars 349 forks source link

What is the future for Microsoft.OData.Client? #1411

Closed cilerler closed 4 years ago

cilerler commented 5 years ago

I wonder if Microsoft.OData.Client will ever support .NET Core 2.2 or .NET Core 3?

If not, it is better to officially deprecated the library so we can move forward with Simple.OData.Client.

Thank you for your time and attention.

robertmclaws commented 5 years ago

I would love to switch everything to SImple.OData.Client and figure out how to generate a TypeScript version from the C# code. I think that would be a really powerful combination that would simplify a lot of things moving forward.

cilerler commented 5 years ago

@robertmclaws trying to move forward with Blazor and want to avoid TypeScript/Javascript as much as I can.

Also, I'm hesitant to move forward with Simple.OData.Client since it doesn't support LINQ based filtering unless OData team says they are done releasing the client. All I want is be able to write .Where(o=>o.Id==111) instead of $filter=Id eq 111 not asking much 😇

My 2 cents says server without client won't get the community momentum and for that reason OData team eventually have to provide .NET and Javascript/Typescript clients.

NetTecture commented 5 years ago

That is your choice - but if you see odata as an open standard, then the current situation is this:

The MS client you can throw out - Simple.Odata.Client does use that, done.

@cilerler Not sure what you ask here, because it does. Ok, instead of ".Where" you have to write ".Filter", but that is a small issue and follows odata naming conventions. The functionality is there. My Simple.Odata.CLient looks like this:

        var serviceProvider = await c.For<OdataApi.ServiceProvider>()
           .Filter(x => x.Account.Identity == reference.Account.Identity)
           .Filter(x => x.Name == reference.Name)
           .FindEntryAsync();

See, there is LINQ style filtering ;)

But Java and Typescript are serious issues. Typescript in particular because no, Blazor is NOT a solution for most companies.

cilerler commented 5 years ago

@NetTecture my bad, I didn't realize that syntax before and I'm OK to use Filter instead of Where that I can compromise. 🤣 Thank you!

But still, I would like to get an official update to know if there will be any Microsoft.OData.Client in the future.

"Blazor is NOT a solution for most companies"

Correct not yet, but it will be since it is Razor based it will get main-stream momentum if the team keeps pushing it the way they have done in last year. WebAssembly is the thing that will stay around. I don't know you but I'm willing to spend hours on a problem on Blazor then Javascript even in this early stage.

ikemtz commented 5 years ago

I'm actually working on a solution to generate a typescript client along with models for communicating with OData. However, I might be taking a slightly different approach than most. I'm leveraging Swagger/Swashbuckle to first generate the spec then generate the typescript from there. It took me a while just to get this far, I should have an npm package in a couple of weeks.

Here's an OData endpoint with Swashbuckle. https://im-wa-cmpo-nrsr.azurewebsites.net/swagger/index.html

robertmclaws commented 5 years ago

@ikemtz That sounds awesome. Look forward to seeing it.

It's relatively straightforward to generate clients from Swashbuckle, but I feel like you lose the power of querying in the process. I've written a very simple FetchClient and a set of generators that go against the EDMX to create a client wrapper... and it works well... but you're manually constructing query URLs. OData really shines when you're using LINQ syntax to construct queries.

@NetTecture your analysis is spot on here. The Microsoft client is so old I don't think it's worth salvaging. It would be a total rewrite, and SODC is so good there isn't much of a point. The only thing I'd consider changing is seeing what kind of benefit you might get from ConcurrentCollections instead of Lists.

I think the best approach is going to be to figure out how to compile Simple.Odata.Client into TypeScript using LinqTS. There are a couple of platforms out there that compile C# into TypeScript, but I have not gotten them to work. yet. Or, a TypeScript version of SODC could be built from scratch with the same API surface. Obviously it would be easier to point a compiler at the project and go "give me TypeScript".

And @NetTecture, Blazor will 100% be an option for companies within the next 18 months. This WebAssembly thing is definitely not going away anytime soon.

@cilerler I'm using OData and Blazor right now, and all I need to make it work is a custom object to contain the parameters from OData payloads. Here's a taste:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using CloudNimble.BlazorEssentials;
using CloudNimble.BurnRate.Core;
using Microsoft.AspNetCore.Blazor;
using Microsoft.AspNetCore.Blazor.Services;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;

namespace BurnRate.Web.Admin.ViewModels
{
    public partial class CompanyTeamsViewModel : ViewModelBase<ConfigurationBase, AppStateBase>
    {

            #region Properties

            /// <summary>
            /// 
            /// </summary>
            public List<CompanyTeam> CompanyTeams { get; set; }

            #endregion

            /// <summary>
            /// 
            /// </summary>
            /// <param name="httpClient"></param>
            public CompanyTeamsViewModel(ConfigurationBase configuration, AppStateBase appState, IUriHelper uriHelper, HttpClient httpClient) : base(configuration, appState, uriHelper, httpClient)
            {
                CompanyTeams = new List<CompanyTeam>();
            }

            /// <summary>
            /// 
            /// </summary>
            /// <returns></returns>
            public async Task Load()
            {
                if (CompanyTeams.Count == 0)
                {
                    var companyTeams = await HttpClient.GetJsonAsync<ODataResultList<CompanyTeam>>($"{Configuration.ApiRoot}CompanyTeams{FilterCriteria}");
                    CompanyTeams.AddRange(companyTeams.Value);
                }
            }

    }
}

You can get the ODataResultList and all the ViewModel goodness here: https://github.com/CloudNimble/BlazorEssentials

NetTecture commented 5 years ago

@ikemtz Care to enlighten me how you got swashbuckle integrating? I never managed to get this working. I have developers who would LOVE me to actually show the odata endpoints in swagger. The metadata document is nice - but not "end user compatible", while swashbuckle is exactly that ;)

@robertmclaws 18 months out IS irrelevant. In my universe we ship a major product update for a customer - next week ;) I look forward to use Blazor in some internal projects, but right now it is just not there where I can ship a product, yet.

earloc commented 5 years ago

We recently moved away from using the oldish OData-Client-Generator to SODC, too. For the TypeScript / Angular world we rolled our own implementation that currently supports the majority of reading-capabilities, including $filter, $orderby, projections via $select, grouping via $apply, etc. . Funnily (and by 'accident'), the API-surface looks extremely similar to what´s SODC is doing, but under the hood it is really just a typed URI builder atm, currently relying on Typings/Interfaces generated via NSwag. So we do not consume the EDMX ourselves, but rather let NSwag spit out models by reading the OpenAPI-/Swagger-document.

All methods leverage keyof and lookup-types to gain a great IntelliSense experience (and also uncover (un)intended renamings of properties, etc. at compile-time)

for simple queries:

it("should allow to filter by two simple properties and discrete values with logical OR operator", () => {
      const query = new Query<Thing>("Things");

      query
        .filter("PropertyA", "=", "SomeValue") //completly assisted typing-experience via keyof T
        .or("PropertyB", "=", "SomeOtherValue");

      const actual = query.toString();
      expect(actual).toBe("Things?$filter=(PropertyA eq 'SomeValue') or (PropertyB eq 'SomeOtherValue')");
    })

Going deeper into the model´s-structure can be written via arrow-functions:

it("should allow to filter by a navigation property and a discrete value", () => {
      const query = new Query<Thing>("Things");

      query.filter(x => x.PropertyA.PropertyC, "=", "SomeValue");

      const actual = query.toString();
      expect(actual).toBe("Things?$filter=(PropertyA/PropertyC eq 'DE')");
    })

groupings can be achieved via something as:

it("should allow to group by single property with a single filter and sum aggregation", () => {
      const query = new Query<Thing>("Things");

      const actual = query
        .filter("PropertyA", "!=", "SomeValue")
        .group.by("PropertyB")
        .aggregate("PropertyA").with.sumAs("TheSum").toString();

      expect(actual).toBe("Things?$apply=filter((PropertyA ne 'SomeValue'))/groupby((PropertyB), aggregate(PropertyA with sum as TheSum))");
    })

All possible query-actions can be mixed and matched as needed.

This whole thing is already wrapped into an npm-package for use by internal projects - but would need further polishing to publish to the community.

Maybe this could be used as a starting point?

robertmclaws commented 5 years ago

@earloc That looks awesome, and I think it could be a great starting point. I can't speak for the Microsoft side of the house, but I think it would be worth discussing, for sure.

ikemtz commented 5 years ago

@NetTecture Getting swagger to work with OData took me a while; longer than I'd like to admit. I'm building a framework that makes this super simple called NRSRx, here's the repo: https://dev.azure.com/ikemtz/_git/NRSRx

Just take a look at any of the OData microservices to see how it works. I'm still working on documentation. This is the NuGet package you'll need https://www.nuget.org/packages/IkeMtz.NRSRx.Core.OData/.

I originally got the idea from @commonsensesoftware when I stumbled upon this repo https://github.com/Microsoft/aspnet-api-versioning.

earloc commented 5 years ago

@robertmclaws: I will have an offline-conversation with my team-mate to check what could get pushed in a repo here and polish up areas that are currently a little too specific for our use cases atm. Shouldn't be much effort, though. I'll drop some links here when we have something together - probably within the coming week.

ikemtz commented 5 years ago

I'm actually working on a solution to generate a typescript client along with models for communicating with OData. However, I might be taking a slightly different approach than most. I'm leveraging Swagger/Swashbuckle to first generate the spec then generate the typescript from there. It took me a while just to get this far, I should have an npm package in a couple of weeks.

Here's an OData endpoint with Swashbuckle. https://im-wa-cmpo-nrsr.azurewebsites.net/swagger/index.html

Update: As promised my npm package is in pre-beta but can be found here. https://www.npmjs.com/package/odata-ts-generator

earloc commented 5 years ago

@robertmclaws: One week can be sooo long :) Sorry for the delay, but my plate was quite full the last couple-o-weeks.

I just pushed an initial version of the mentioned lib: https://github.com/earloc/odata-uri-builder

Whlile bootsrapping the project, I also stumbled upon https://github.com/cbrianball/ts-odata-client They do very similar things - and the V3/V4-agnostic architecture also looks interesting.

sasivishnu commented 5 years ago

Hi,

Just for confirmation, whats the conclusion? Go with Simple.OData.Client? We have to use OData in our upcoming Xamarin.Forms app project since our server API uses OData (Microsoft.Data.OData and Edm library)

Also, any sample/suggestions to use OData in Xamarin.Forms will be helpful. Thanks

unchase commented 5 years ago

Unchase OData Connected Service - extension for Visual Studio 2017/2019 that supports client-code generation for .Net Core applications.

NetTecture commented 5 years ago

And here is my take. WIL Lbe a dotnet core global tool so it integrated into build scripts if wanted. WOrking on it now.

NetTecture commented 5 years ago

https://github.com/NetTecture/CodeCore.ODataClient

rahul7720 commented 4 years ago

@robertmclaws trying to move forward with Blazor and want to avoid TypeScript/Javascript as much as I can.

Also, I'm hesitant to move forward with Simple.OData.Client since it doesn't support LINQ based filtering unless OData team says they are done releasing the client. All I want is be able to write .Where(o=>o.Id==111) instead of $filter=Id eq 111 not asking much 😇

My 2 cents says server without client won't get the community momentum and for that reason OData team eventually have to provide .NET and Javascript/Typescript clients.

Another reason I like the Odata Client Code Generator because it has in-built entity tracking feature (like EF) and it will only sends the updated property to the server by calling the PATCH method on the server, which is not available in Simple.Odata.Client.

cilerler commented 4 years ago

@mikepizzo I believe we should have an official client for at least for C# and Typescript, would you share your/team's thoughts on that, please? Thanks in advance.

mikepizzo commented 4 years ago

Absolutely; having a good integrated client story was one of the most important aspects to getting adoption in the early days of OData. While the client has been neglected over the past few years while we've concentrated on rapidly iterating the service and core libraries to address new platforms and protocol features, we brought an excellent group of developers on board late last year whose initial focus is to devote more attention to the client and tools story. You'll see more activity on the OData Client libraries and tools here.

We hugely appreciate the work the community has done through projects such as the OData Simple Client, Unchase Connected Services, and other shared OData libraries and tools, and look forward to the same community support as engage more deeply to contribute to a rich set of tools and libraries. Toward this end, we are planning to move all of the .NET OData libraries and tools to the .NET Foundation, as we have successfully done with RESTier, in order to encourage and enable more direct contributions from an active community.

While .NET is certainly our expertise and focus, we are looking at ways we can invest in libraries outside of .NET and will again be relying even more on the talents and enthusiasm of the community to support and enhance such efforts.

It's an exciting time for me to see many of our efforts coming together with RESTier soon to release, a new OData 4.01 specification that extends OData 4.0 with simplified patterns and new functionality, and renewed investments in client libraries and tools, and I humbly thank this community for its continued support.

rahul7720 commented 4 years ago

UPDATE MARCH 2020 Seems Microsoft Odata team is continuously updating Odata Client. I can see the Odata Connected Service extension is updated to Version 0.4 which supports VS2019. https://marketplace.visualstudio.com/items?itemName=laylaliu.ODataConnectedService

weitzhandler commented 4 years ago

Yes. It's now at 0.6.0. I checked and it also deals with inheritance and DI better, to my taste.

In the other hand, Simple.OData.Client seems pretty neglected.

Does that make OData connected service be the most recommended OData client at the moment?

weitzhandler commented 4 years ago

Does that make OData connected service be the most recommended OData client at the moment?

Got an official answer here, quoting:

@weitzhandler Thanks for the feedback. Yes, it is recommended to use Microsoft OData Connected Service and Microsoft.OData.Client for your client development since we are committed in supporting these libraries going forward.

buchatsky commented 2 years ago

Whlile bootsrapping the project, I also stumbled upon https://github.com/cbrianball/ts-odata-client

There is one more TS Odata client: jinqu-odata. It is LINQ-like and resembles Simple.OData.Client

drventure commented 2 years ago

Does the Odata Connected Client now support deep inserts/updates. I see it's now at 7.11.

I know 7.9.3 did not appear to.