Closed cilerler closed 4 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.
@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.
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.
@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.
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
@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
@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.
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?
@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.
@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.
@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.
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
@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.
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 OData Connected Service - extension for Visual Studio 2017/2019 that supports client-code generation for .Net Core applications.
And here is my take. WIL Lbe a dotnet core global tool so it integrated into build scripts if wanted. WOrking on it now.
@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.
@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.
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.
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
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?
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.
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
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.
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.