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

Provide an API experience that scales down well and is easier to learn #27724

Closed
2 tasks done
Tracked by #5397 ...
glennc opened this issue Oct 22, 2020 · 7 comments
Closed
2 tasks done
Tracked by #5397 ...

Provide an API experience that scales down well and is easier to learn #27724

glennc opened this issue Oct 22, 2020 · 7 comments
Assignees
Labels
affected-medium This issue impacts approximately half of our customers area-web-frameworks enhancement This issue represents an ask for new feature or an enhancement to an existing one Epic Groups multiple user stories. Can be grouped under a theme. Priority:1 Work that is critical for the release, but we could probably ship without severity-nice-to-have This label is used by an internal tool Theme: cloud native Theme: .NET appeals to new developers
Projects
Milestone

Comments

@glennc
Copy link
Contributor

glennc commented Oct 22, 2020

Title: Provide an API experience that scales down well and is easier to learn

ASP.NET Core does not provide a smooth way to scale an API down. We provide MVC which has lots of features, but also lots of concepts to learn. We want to provide experiences for building APIs that can start simpler, with a clearer getting started experience, and can smoothly progress to controllers if desired.

Our results from Feather studies and some of our Cloud Native user studies have shown that developers new to .NET react well to more simplified API experiences, and we think that also dovetails well with the Cloud Native theme as frequently the complexity that Controllers are designed to allow you to manage are instead managed across process/project boundaries.

This epic will allow us to enhance our API offering by extracting features currently only available in MVC, allowing them to be used outside of MVC. The intent is to allow these extracted features to be used in a functions/lambda model as well as a controller model of APIs. We started this work with Endpoint routing, but today that experience lacks a lot of desirable features, like model binding and validation, and doesn't have a clear story for better code organization once you grow beyond what fits well in an inline lambda.

Initial Principles/Goals:

  1. Improve the endpoint routing APIs to the point that we could make it the default API story in ASP.NET Core
    1. Allow using features that are currently only available in MVC that make sense (model binding is the big one)
    2. Provide a smooth migration experience from inline lambda, to functions, to classes or controllers as code organization for an API
  2. Don't create APIs for small apps. The idea is not to create a less capable API experience. Instead we want to allow simple things to be simple. Allowing seamless mixing of controllers and non-controllers, sharing of all the concepts and infrastructure that make sense.
  3. Ensure APIs are good for our single-file/trimming/AOT experiences. Ensuring that a small API also produces a small binary output when built.
  4. Improve the performance of MVC by getting middleware-like perf for extracted components and only paying of those components when you need them.

Sub-issues

  1. New lightweight programming model for APIs (Simplify API-building experience without controllers #27347)
  2. User learning arc for new minimal/focused ASP.NET Core API experience (User learning arc for new minimal/focused ASP.NET Core API experience #30580)
@halter73 halter73 transferred this issue from dotnet/core Nov 11, 2020
@halter73 halter73 added Epic Groups multiple user stories. Can be grouped under a theme. Theme Groups multiple epics. Theme: cloud native Theme: .NET appeals to new developers and removed Theme Groups multiple epics. labels Nov 11, 2020
@halter73 halter73 added this to the 6.0.0 milestone Nov 11, 2020
@StefanBertels
Copy link

Hopefully this simplification approach will make DI (dependency injection) at least optional and reduce "filter magic".
Meanwhile I built my own small WebApi host helper (wrapper library) that solves something like this -- I just have to create some MyController class, reference my helper lib and add a one-liner somewhere (e.g. Main) to start background kestrel to get a REST api using json.
Getting rid of boiler plate code was a challenge because default code relies heavily on DI and filters.

@Pilchie Pilchie added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Dec 15, 2020
@Pilchie Pilchie added the Priority:2 Work that is important, but not critical for the release label Jan 20, 2021
@davidfowl davidfowl added Priority:1 Work that is critical for the release, but we could probably ship without and removed Priority:2 Work that is important, but not critical for the release labels Jan 23, 2021
@mkArtakMSFT mkArtakMSFT moved this from Proposed to Committed in .NET 6.0 Jan 29, 2021
@mattwelke
Copy link

mattwelke commented Feb 18, 2021

Interesting design goal for .NET 6! I think this is a great idea. I've had times when I couldn't sell people on ASP.NET because they wanted a banana, but not the gorilla and the forest too.

We started this work with Endpoint routing, but today that experience lacks a lot of desirable features, like model binding and validation, and doesn't have a clear story for better code organization once you grow beyond what fits well in an inline lambda.

Call me crazy, but I like the fact that I don't have to use model binding if I don't want to. I love the simplicity of just "here's a request, it has a Content-Type header and a big string, do with it what you will". Once I get a better understanding of my domain, understanding more what my app needs to do each time, I can write centralized code to help me with it, or seek out libraries or parts of the framework (like model binding) that help me with those things.

But, I get that it's not ideal to force people to choose between barebones approaches like that and full blown MVC. It should be a spectrum. I agree with that design goal! But please don't lose that far end of the spectrum where we get to do a lot of stuff by ourselves without .NET getting in the way.

Hopefully this simplification approach will make DI (dependency injection) at least optional

This is a great example of something I wish was optional. For singleton dependencies, I write code like:

// entrypoint.js
const myDep = ...;
app.get('my-route', () => { myDep.somethingIWantToDo(); });

Express.js lets me do that when I want to, and I love it.

I usually want a DI container when I have more complex dependency needs like scoped dependencies.

reduce "filter magic"

Another good example that I agree with. Without filters affecting the request/response flow, I don't need to constantly search through the ASP.NET docs to see what it's doing to my request.

With the NancyFx project winding down (https://github.com/NancyFx/Nancy), this is a great opportunity to give people a barebones C# API experience if they want it.

@branko-d
Copy link

I think ASP.NET Core should aspire to be a great platform for producing strongly-typed APIs, which can be consumed from TypeScript in automated way. I've picked TypeScript specifically because TypeScript + React/Vue/Angular + ASP.NET Core could be a killer combo, if only we could lower the friction of getting the data from/to the server.

Let's just write an API method in C# and the strongly-typed TypeScript wrapper would be generated and ready to be consumed with no/minimal tweaking. The "advanced" C#/.NET features would be handled out-of-box, such as generics, async enumerables, streams, exceptions, various BCL data structures etc. The XML documentation comments would be translated to the JSDoc equivalent.

We have used NSwag for this in the past with... acceptable results. We needed to heavily customize the NSwag's Liquid templates to integrate the resulting TypeScript code with our Web app's log-in, progress indication and error handing, and still had to manually write TypeScript wrappers in some cases (notably for streaming file content). We had to dig through the NSwag's source on GitHub source to figure-out what can we actually use in these templates. We had to dig more to understand how to properly integrate NSwag into our build process. We had to battle silent data loss and weird behavior. Etc, etc...

It would be great if we could achieve the same just using built-in APS.NET Core mechanisms which would be better documented, better tested, better supported and just "better" generally.

Sorry if this sounds ranty, it's just that APIs are at the heart of so many things these days, and APS.NET's API story seems missing in action. Yes, CORBA's and COM's heydays are long gone, but their IDL, and the seamless generation of client code from IDL is still something we can learn from, IMO.

Or am I speaking out of ignorance?

@mkArtakMSFT mkArtakMSFT added affected-medium This issue impacts approximately half of our customers enhancement This issue represents an ask for new feature or an enhancement to an existing one severity-nice-to-have This label is used by an internal tool labels Feb 18, 2021 — with ASP.NET Core Issue Ranking
@ardalis
Copy link
Contributor

ardalis commented Feb 18, 2021

Hopefully new features will make it easier to add API endpoints as single files/classes rather than having to group them into controllers. My ApiEndpoints package has proven fairly popular and basically just enforces having a single endpoint on controllers. It works quite well.

@mattwelke
Copy link

@branko-d

Let's just write an API method in C# and the strongly-typed TypeScript wrapper would be generated and ready to be consumed with no/minimal tweaking.

We're in the process of learning about Protobuf at my work and it seems to help with this use case. You can have a language agnostic schema definition and then get code generated for you in C# and TypeScript. But you do have to use it with gRPC services (not HTTP services) if you want all code generated for you, and the C# Protobuf compiler has established the pattern of a "code first" C# only approach, where you annotate C# classes and get protobuf schemas generated for you. So I could see precedent set here for a new tool that takes C# controllers, as you described, and generates TypeScript code that can act as a client for you, including the schema of the model.

@lonix1
Copy link
Contributor

lonix1 commented Jul 6, 2021

The ApiEndpoints mentioned above is described as "Razor Pages for web APIs". That's precisely what's needed to simplify a WebAPI project - one "endpoint" class per endpoint, rather than a fat controller with dozens of unrelated actions.

Make it simple like it is in other platforms, e.g. Node's Express.

Ideally implement that library into the framework itself. It's designed well and heavily used (check nuget stats - the devs have spoken).

@mkArtakMSFT mkArtakMSFT added area-web-frameworks and removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels Sep 21, 2021
@rafikiassumani-msft
Copy link
Contributor

Closing this issue. Remaining Open API items will be addressed in NET7. See the following tracking issue: #37098

.NET 6.0 automation moved this from Committed to Completed Oct 8, 2021
@msftbot msftbot bot locked as resolved and limited conversation to collaborators Nov 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affected-medium This issue impacts approximately half of our customers area-web-frameworks enhancement This issue represents an ask for new feature or an enhancement to an existing one Epic Groups multiple user stories. Can be grouped under a theme. Priority:1 Work that is critical for the release, but we could probably ship without severity-nice-to-have This label is used by an internal tool Theme: cloud native Theme: .NET appeals to new developers
Projects
.NET 6.0
  
Completed
Development

No branches or pull requests