Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BLAZOR API review #4050

Closed
20 tasks done
danroth27 opened this issue Nov 16, 2018 · 9 comments
Closed
20 tasks done

BLAZOR API review #4050

danroth27 opened this issue Nov 16, 2018 · 9 comments
Assignees
Labels
area-blazor Includes: Blazor, Razor Components Done This issue has been fixed task

Comments

@danroth27
Copy link
Member

danroth27 commented Nov 16, 2018

Edit: @rynowak hijacking top post for great justice

Framing Blazor API reviews

I'm suggesting that we bucket API review work into areas based on the user-impact and expected usage of APIs, and from there prioritize and time-box some of the decision making. I'm hoping to use this document to paint a high-level picture rather than "do the work" for everything at once.

I don't think it's super reasonable to have us sit in a room and "do a pass" given how many of these APIs we've built up over time - the discussion would quickly get unfocused. I want everyone's input and involvement in making the first release of Blazor awesome - so I'm going to suggest that we do initial reviews and discussions on github or email and then have meetings as-needed.

Here's a quick shout-out for all of the ideas that were explicitly mentioned in the github issue.

  • Review all of our startup API for both client-side and server-side
  • Startup Code (various suggestions)
  • Mark all attributes sealed (and review AttributeUsage)
  • Develop a style-guide for components and make the built-in ones conform
  • Figure out what to do with our HttpClient extension methods
  • Do we want to develop a naming convention for types that are intended for JS interop only (like is commonly done with P/Invoke)

It's been a long time since some of us started work on Blazor (over a year and a half for Steve). We should look at the details of everything important with fresh eyes, and make sure it's as good as it can be. We've gone up until this point doing the best we can right now, but we're about to cross the threshold where all of these decisions become permanent. It's scary! But at least we're doing it together.

What are we doing?

I think there are probably two beneficiaries of an API review - us, and unsurprisingly our users. While it might seem like we want different things, I think we usually want the same things in this area. If we can craft APIs with good ergonomics, it's easy to talk about with customers, or write documentation for. If we create good APIs it's easy to scale them up as we work on the framework.

  • Simplicity (few namespaces, overloads you want are easy to find, avoid tricky patterns)
  • Consistency (predictability, portability)
  • Horizontal Scalability (API and overloads can grow as functionality is added)

Often this means that we need to do hard work so that users have a good experience. If you've worked on MVC for a while I'm sure you can think of a few examples where we wish we did better 😉.

Areas of focus

Areas are in rough order of priority and attempt to call out of some of things that are important to review and decide. Please feel free to suggest your own ideas or disagreements - but keep in mind that we will have to time-box this work (both reviewing and changing).

I'm not attempting to make a list of everything that has to be reviewed.

Here's a rough categorization and catalog of all of the APIs that exist as of a week ago.

https://microsoft.sharepoint.com/:x:/t/DotNetTeam/ERLn4oNI3ZNHvyqRdklMoBUBKTxzD4jOCbmEO0u50p-zqA?e=4vdrl1

Use: \\fxcore\tools\apps\ApiReviewer to generate a spreadsheet like this.

Work Items

Packages/assemblies

There was a proposal circulated via email to try and align and packages around a single name, as well as clean up some unclarities.

image

The immediate action item here is to rename M.A.C.Browser and M.A.C.Browser.JS.

  • Rename M.A.C.Browser -> M.A.C.Web
  • Rename M.A.C.Browser.JS -> M.A.C.Web.JS

ComponentBase and related types

  • ComponentBase
  • IComponent
  • IHandleEvent and other lifecycle APIs
  • RenderHandle
  • ParameterAttribute
  • CascadingParameterAttribute
  • IComponentContext
  • InjectAttribute
  • RouteAttribute

What we're looking for here is the consistency, naming and predictability of the APIs on ComponentBase.

Things I'm personally interested in:

  • Do we have too many lifecycle events?
  • Do we anticipate adding more over time?
  • Do we have fragile-base-class extensibility points?

I'm concerned about the naming of things like InjectAttribute and RouteAttribute - we're parking these names in the components namespace, without an attempt to reconcile them with existing or future types.

Built-in components

  • InputText and other form types
  • EditForm
  • AuthorizeDisplay
  • Router
  • NavLink

We may choose to break some of these off into their own discussions depending on the size.

On my mind here is coming up with a vocabulary, or a style-guide for component naming and trying to apply it to these and see if it fits.

Startup experience

The startup experience includes everything Blazor adds to the Startup.cs file:

  • Extensions on IServiceCollection
  • Extensions on IEndpointRouteBuilder

I'm leaving aside client-side Blazor for 3.0 which has a lot more startup code, but doesn't need to be locked down.

What we're looking for here is consistency with the rest of the stack and horizontal scalability. Do we expose the right options? Do we expose details of underlying components like SignalR where important?

JS Interface

The blazor.*.js files define an API for use in bootstrapping Blazor applications, as well as configuring features like reconnection. We need to do a full pass over this since this API has grown organically.

Top-level features

Authentication

  • AuthenticationState
  • AuthenticationStateProvider
  • AuthenticationStateChangedHandler

These APIs are relatively recent, and seem pretty polished.

Parameter Infrastructure

  • Parameter
  • ParameterCollection
  • ParameterEnumerator
  • ParameterCollectionExtensions

I think the design of these types and naming of Parameter needs a review. ParameterCollectionExtensions probably has no reason to be an extension method.

HttpClient extensions

  • HttpClientJsonExtensions

Can we ship this in a Blazor-specific (non-ASP.NET Core Shared Framework assembly)? I have serious concerns about us shipping HttpClient extensibility in the components assembly, and addressing those concerns will break our present our future.

IUriHelper and navigation

  • IUriHelper
  • UriHelperBase
  • NavigationException

I'm concerned about the design of this API surface, the naming and its future maintainability. This should probably be an abstract class (or broken up into separate concerns). The naming is too similar to IUrlHelper in MVC, and the naming feels outdated (referential of helpers in Rails).

  • INavigationInterception
  • LocationChangedEventArgs
  • NavLinkMatch

These types are in Microsoft.AspNetCore.Components.Routing and probably don't belong there unless they are oriented around something more central. This is a namespace with few types.

ElementRef

  • ElementRef

Should this be renamed to ElementReference? More formal. Should this be in Microsoft.AspNetCore.Components.Browser?

Forms

Everything in Microsoft.AspNetCore.Components.Forms - this is a top level API for extensibility and integration with forms, we need to review all of this.

  • EditContext
  • EditContextDataAnnotationsExtensions
  • EditContextExpressionExtensions
  • EditContextFieldClassExtensions
  • FieldChangedEventArgs
  • FieldIdentifier
  • ValidationMessageStore
  • ValidationMessageStoreExpressionExtensions
  • ValidationRequestedEventArgs
  • ValidationStateChangedEventArgs

Layouts

  • LayoutAttribute
  • LayoutComponentBase

EventCallback and Event Handler types

  • EventCallback
  • UIEventArgs
  • UIMouseEventArgs and other browser/DOM specific APIs like DataTransfer
  • EventCallbackFactory and extension methods

Should UIMouseEventArgs and other DOM-related types life in Microsoft.AspNetCore.Components.Browser?

We should review the EventCallbackFactory extensions and make sure they aren't too gross.

Public infrastructure

These are infrastructure-ish things that need to be public, either to preserve layering/extensibility or to because they are useful to users.

RenderTreeBuilder

The RenderTreeBuilder needs to be public so it can be targeted by the compiler. It's also useful for really advanced component authors that need to author in C# for any reason.

We should do a pass over these APIs for consistency and naming, but I think largely this is pretty good.

We should consider whether we can make GetFrames() internal.

The namespace Microsoft.AspNetCore.Components.RenderTree probably is too specific. This should be in Microsoft.AspNetCore.Components.Rendering.

IDispatcher

The IDispatcher is hiding out here in the .Rendering namespace. We should consider moving it somewhere more top-level unless we fill up .Rendering with other stuff. I'm making this suggestion because IDispatcher doesn't touch any of our other APIs in this namespace.

Compiler infrastructure

There's a variety of types that are in the top-level namespace that should almost certainly not be featured so prominently. These are implementation details of what the compiler does, and usually don't make sense for a user to call. We can't really remove anything from these names, so they will likely become more mess over time. We should put all of these types in a dedicated namespace so they are hidden.

  • BindAttributes
  • BindElementAttribute
  • BindInputElementAttribute
  • BindMethods
  • EventHandlerAttribute
  • EventHandlers
  • RuntimeHelpers

Implementation Details

I'm really concerned about the number and kinds of things that are public. We haven't done a pass yet and trying to hide implementation details yet, but I think it's warranted.

The big risk here is the Renderer, RenderBatch and everything else in .Rendering (besides IDispatcher). We could definitely tell people not to use these types, but the reality is that won't stop them. We need to preserve our ability to work on the render tree format. I don't think we have a critical scenario in 3.0 where anyone but us writes a rendering engine.

Appendix A: Links to reference sources

Special mention: no ref assembly for .js Browser.JS

Appendix B: Totally ignorable

  • Microsoft.AspNetCore.Blazor.Build has no APIs
  • Microsoft.AspNetCore.Blazor.DevServer has no APIs
  • Microsoft.AspNetCore.Blazor.Templates has no APIs
  • Microsoft.VisualStudio.BlazorExtension has no APIs
@danroth27 danroth27 added bug This issue describes a behavior which is not expected - a bug. area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels Nov 16, 2018
@danroth27 danroth27 added this to the 3.0.0-preview2 milestone Nov 16, 2018
@SteveSandersonMS
Copy link
Member

  • Rename UseServerSideBlazor<TStartup> to UseComponents<TStartup> (or maybe UseInteractiveComponents<TStartup>, if we want to emphasize that you don't need this if you're doing pure prerendering only)
  • Equivalent for AddServerSideBlazor

What else?

@rynowak rynowak changed the title Razor Components API cleanup Razor Components API review Jan 3, 2019
@mkArtakMSFT mkArtakMSFT added 1 - Ready task and removed bug This issue describes a behavior which is not expected - a bug. labels Jan 15, 2019
@SteveSandersonMS SteveSandersonMS added the area-blazor Includes: Blazor, Razor Components label Feb 6, 2019
@mkArtakMSFT mkArtakMSFT removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels May 9, 2019
@rynowak
Copy link
Member

rynowak commented May 14, 2019

Make all attributes sealed: #10236 (comment)

@rynowak rynowak changed the title Razor Components API review BLAZOR API review May 14, 2019
@rynowak
Copy link
Member

rynowak commented May 15, 2019

Consider the vocabulary for the components we ship: https://github.com/aspnet/AspNetCore/pull/10227/files#r284387196

@SteveSandersonMS
Copy link
Member

Figure out how to ship helpers like HttpClient.GetJsonAsync<T> that will work in components that run on both server and client (so we need it to be the same method in both places, not just similar-looking extension methods or such)

So it needs to be in CoreFX or Microsoft.AspNetCore.Metadata, if not in a Components package directly.

@danroth27
Copy link
Member Author

I think we need to do some work on the shape of the HttpClient JSON helpers as well. As they stand, you don't have any reasonable way of handling responses other than a 200. I think what we want is closer to the Web API Client model, but tied specifically to JSON (no support for additional formatters or content negotiation).

@rynowak
Copy link
Member

rynowak commented Jun 5, 2019

I've updated the top post with some initial framing and throughts. I did a pass through the Components assembly so far, and plan to go through others and update the notes.

I'm also going to put together a cool spreadsheet to help with this.

@SteveSandersonMS
Copy link
Member

@rynowak This is great! I've also added a section on "Packages/assemblies" since it's likely we'll want to consider some renaming at that level.

@rynowak
Copy link
Member

rynowak commented Jun 5, 2019

awesome. I know I've missed stuff because I only looked through a single assembly so far.

@SteveSandersonMS
Copy link
Member

@rynowak rynowak added Done This issue has been fixed and removed 1 - Ready labels Aug 17, 2019
@rynowak rynowak closed this as completed Aug 17, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Dec 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components Done This issue has been fixed task
Projects
None yet
Development

No branches or pull requests

4 participants