Skip to content

Commit 5515961

Browse files
authored
Update README doc samples to latest (#188)
* Update README doc samples to latest closes #172 . Also fixed navigation. Added links to explain OCP and SRP * Update README.md closes #171 * Update README.md
1 parent bd1b256 commit 5515961

File tree

3 files changed

+17
-11
lines changed

3 files changed

+17
-11
lines changed

README.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ For version 3.0 we implemented a new way to define the base classes using "fluen
6060

6161
[7. Related Articles](#7-related-articles)
6262

63-
[8. Videos and Podcasts](#8-videos-podcasts)
63+
[8. Videos and Podcasts](#8-videos-and-podcasts)
6464

65-
[9. Related / Similar Projects](#8-related--similar-projects)
65+
[9. Related / Similar Projects](#9-related--similar-projects)
6666

67-
[10. Projects Using ApiEndpoints](#9-projects-using-apiendpoints)
67+
[10. Projects Using ApiEndpoints](#10-projects-using-apiendpoints)
6868

69-
[11. Success Stories and Testimonials](#10-success-stories-and-testimonials)
69+
[11. Success Stories and Testimonials](#11-success-stories-and-testimonials)
7070

7171
## 1. Motivation
7272

@@ -97,7 +97,7 @@ Most REST APIs have groups of endpoints for a given resource. In Controller-base
9797
I'll look to add detailed documentation in the future but for now here's all you need to get started (you can also check the sample project):
9898

9999
1. Add the [Ardalis.ApiEndpoints NuGet package](https://www.nuget.org/packages/Ardalis.ApiEndpoints/) to your ASP.NET Core web project.
100-
2. Create Endpoint classes by inheriting from either `BaseEndpoint<TRequest,TResponse>` (for endpoints that accept a model as input) or `BaseEndpoint<TResponse>` (for endpoints that simply return a response). For example, a POST endpoint that creates a resource and then returns the newly created record would use the version that includes both a Request and a Response. A GET endpoint that just returns a list of records and doesn't accept any arguments would use the second version.
100+
2. Create Endpoint classes by inheriting from either `EndpointBaseSync<TRequest,TResponse>` (for endpoints that accept a model as input) or `EndpointBaseSync<TResponse>` (for endpoints that simply return a response). For example, a POST endpoint that creates a resource and then returns the newly created record would use the version that includes both a Request and a Response. A GET endpoint that just returns a list of records and doesn't accept any arguments would use the second version.
101101
3. Implement the base class's abstract `Handle()` method.
102102
4. Make sure to add a `[HttpGet]` or similar attribute to your `Handle()` method, specifying its route.
103103
5. Define your `TResponse` type in a file in the same folder as its corresponding endpoint (or in the same file if you prefer).
@@ -197,7 +197,7 @@ Below are what I expect will be some common questions:
197197

198198
### How do I use shared routing conventions?
199199

200-
~~If you want to create a common route template for all or some subset of your Endpoints, simply create a BaseEndpoint of your own that inherits from `Ardalis.Api.Endpoints.BaseEndpoint` and add a `[Route]` attribute to it.~~
200+
If you want to create a common route template for all or some subset of your Endpoints, simply create a EndpointBaseSync of your own that inherits from `Ardalis.Api.Endpoints.EndpointBaseSync` and add a `[Route]` attribute to it.
201201

202202
After refactoring to use the fluent generics pattern, there is no longer a way to use a base class for a default route. Instead, you should define your routes as constants which you can store in a central file or in each Request DTO (the sample shows this approach).
203203

@@ -255,9 +255,15 @@ For more information, take a look at [this discussion](https://github.com/ardali
255255
There's an example in the [sample app](https://github.com/ardalis/ApiEndpoints/blob/main/sample/SampleEndpointApp/Endpoints/Authors/ListJsonFile.cs) that shows how to set this up and return a File actionresult. For the base type, just use the `WithoutResponse` option and in the endpoint handler return `File()`.
256256

257257
### How can I use model binding to pull values from multiple places, like `[FromRoute]`, `[FromBody]`, etc.?
258-
258+
#172
259259
The base endpoints only expose a single model type which is used on the Handle method, so you can't easily add additional parameters to the Handle method. However, you can put as many properties on the associated Request DTO as you want, and model binding allows you to set the same attributes per property as you would have set per parameter on the action method. See [Model Binding Docs](https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding) and [discussion here in issue 42](https://github.com/ardalis/ApiEndpoints/issues/42)
260260

261+
### How can I use streaming from server to client?
262+
There's an example in the [sample app](https://github.com/ardalis/ApiEndpoints/blob/main/sample/SampleEndpointApp/Endpoints/Authors/Stream.cs) that shows how to set this up and return an `IAsyncEnumerable<T>`. For the base type, just use the `WithAsyncEnumerableResult<T>` option and in the endpoint handler yeld return after awaiting your async code.
263+
264+
> Note: streaming with IAsyncEnumerable does not work within Swagger Ui. Use curl to test this functionality
265+
> ``` bash
266+
> curl -X "GET" "https://localhost:44338/api/Authors/stream" -H "accept: text/plain"
261267
## 6. Roadmap
262268
263269
The following are some things I'd like to add to the project/package.
@@ -268,15 +274,15 @@ Visual Studio and/or CLI item templates would make it much easier to create Endp
268274
269275
### Route Conventions
270276
271-
One thing that Controllers do have is built-in support in the framework to use their name in routes (e.g. "/[controller]/{id?}"). Currently in the sample app routes are hard-coded strings. It would be nice if there were an easy way to use a convention based on foldername or namespace or something (using foldername would align with how Razor Pages routing works).
277+
One thing that Controllers do have is built-in support in the framework to use their name in routes (e.g. "`[controller]/{id?}`"). Currently in the sample app routes are hard-coded strings. It would be nice if there were an easy way to use a convention based on foldername or namespace or something (using foldername would align with how Razor Pages routing works).
272278
273279
## 7. Related Articles
274280
275281
- [Moving from Controllers and Actions to Endpoints](https://ardalis.com/moving-from-controllers-and-actions-to-endpoints-with-mediatr)
276282
- [Decoupling Controllers with ApiEndpoints](https://betweentwobrackets.dev/posts/2020/09/decoupling-controllers-with-apiendpoints/)
277283
- [Fluent Generics](https://tyrrrz.me/blog/fluent-generics)
278284
279-
## 8 Videos and Podcasts
285+
## 8. Videos and Podcasts
280286
281287
- [Clean up your .NET Controllers with API Endpoints by Nick Chapsas](https://www.youtube.com/watch?v=SDu0MA6TmuM&ab_channel=NickChapsas)
282288
- [The .NET Docs Show - Controllers are Dinosaurs and the Case for API Endpoints](https://www.youtube.com/watch?v=9oroj2TmxBs&ab_channel=dotNET)

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ When working with ASP.NET Core API Endpoints your project won't need any Control
1414

1515
Most REST APIs have groups of endpoints for a given resource. In Controller-based projects you would have a controller per resource. When using API Endpoints you can simply create a folder per resource, just as you would use folders to group related pages in Razor Pages.
1616

17-
Instead of Model-View-Controller (MVC) the pattern becomes Request-EndPoint-Response(REPR). The REPR (reaper) pattern is much simpler and groups everything that has to do with a particular API endpoint together. It follows SOLID principles, in particular SRP and OCP. It also has all the benefits of feature folders and better follows the Common Closure Principle by grouping together things that change together.
17+
Instead of Model-View-Controller (MVC) the pattern becomes Request-EndPoint-Response(REPR). The REPR (reaper) pattern is much simpler and groups everything that has to do with a particular API endpoint together. It follows SOLID principles, in particular [SRP](https://en.wikipedia.org/wiki/Single-responsibility_principle) and [OCP](https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle). It also has all the benefits of feature folders and better follows the Common Closure Principle by grouping together things that change together.
1818

1919
## Installing Ardalis.ApiEndpoints
2020

sample/SampleEndpointApp/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ dotnet ef database update
2424

2525
## Duplicate Code in Endpoints
2626

27-
If the duplicate dependency code in the endpoints bothers you, you can avoid it easily by creating your own `BaseAppEndpoint` classes that inherit from `BaseEndpoint`. These can expose as properties any common dependencies like loggers, mappers, or generic repositories, and then use an IOC container's property injection feature to ensure they're always populated when the endpoint is created.
27+
If the duplicate dependency code in the endpoints bothers you, you can avoid it easily by creating your own `AppEndpointBaseSync` classes that inherit from `EndpointBaseSync`. These can expose as properties any common dependencies like loggers, mappers, or generic repositories, and then use an IOC container's property injection feature to ensure they're always populated when the endpoint is created.

0 commit comments

Comments
 (0)