{"id":15091139,"url":"https://github.com/nikiforovall/result-endpoints-template","last_synced_at":"2025-10-09T15:31:24.563Z","repository":{"id":253412832,"uuid":"843370636","full_name":"NikiforovAll/result-endpoints-template","owner":"NikiforovAll","description":"Explore the use of TypedResults in .NET endpoints to achieve a consistent and strongly typed APIs","archived":false,"fork":false,"pushed_at":"2024-08-17T19:51:32.000Z","size":30,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-30T05:31:40.168Z","etag":null,"topics":["aspnetcore","dotnet","openapi","template","webapi"],"latest_commit_sha":null,"homepage":"https://nikiforovall.github.io/dotnet/2024/08/17/result-endpoints.html","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NikiforovAll.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-16T11:17:23.000Z","updated_at":"2024-11-18T05:31:06.000Z","dependencies_parsed_at":"2024-10-14T05:01:15.213Z","dependency_job_id":null,"html_url":"https://github.com/NikiforovAll/result-endpoints-template","commit_stats":{"total_commits":5,"total_committers":1,"mean_commits":5.0,"dds":0.0,"last_synced_commit":"764686ec53819c68b54fb51117ca77a4e18b6563"},"previous_names":["nikiforovall/result-endpoints-template"],"tags_count":3,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NikiforovAll%2Fresult-endpoints-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NikiforovAll%2Fresult-endpoints-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NikiforovAll%2Fresult-endpoints-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NikiforovAll%2Fresult-endpoints-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NikiforovAll","download_url":"https://codeload.github.com/NikiforovAll/result-endpoints-template/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235834919,"owners_count":19052505,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aspnetcore","dotnet","openapi","template","webapi"],"created_at":"2024-09-25T10:35:50.271Z","updated_at":"2025-10-09T15:31:14.549Z","avatar_url":"https://github.com/NikiforovAll.png","language":"CSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Nall.ResultEndpoints.Template\r\n\r\n[![Build](https://github.com/NikiforovAll/result-endpoints-template/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/NikiforovAll/result-endpoints-template/actions/workflows/build.yml)\r\n[![CodeQL](https://github.com/NikiforovAll/result-endpoints-template/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/NikiforovAll/result-endpoints-template/actions/workflows/codeql-analysis.yml)\r\n[![NuGet](https://img.shields.io/nuget/dt/Nall.ResultEndpoints.Template.svg)](https://nuget.org/packages/Nall.ResultEndpoints.Template)\r\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\r\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/nikiforovall/result-endpoints-template/blob/main/LICENSE.md)\r\n\r\nThis is a template for creating a new minimal API project with [Ardalis.ApiEndpoints](https://github.com/ardalis/ApiEndpoints) that utilizes the TypedResults in Endpoint (aka replacement for MVC Controllers for Web APIs).\r\n\r\n```csharp\r\npublic class HelloWorld : EndpointBaseSync.WithRequest\u003cstring\u003e.WithResult\u003cOk\u003cstring\u003e\u003e\r\n{\r\n    [EndpointSummary(\"Says hello\")]\r\n    [EndpointDescription(\"Says hello based on the request\")]\r\n    [Tags(\"Hello\")]\r\n    [EndpointName(nameof(HelloWorld))]\r\n    [HttpGet(\"/hello-world\")]\r\n    public override Ok\u003cstring\u003e Handle([FromQuery(Name = \"q\")] string request)\r\n    {\r\n        if (request == \"error\")\r\n        {\r\n            throw new Exception(\"Something went wrong...\");\r\n        }\r\n\r\n        return TypedResults.Ok($\"Hello, {request}\");\r\n    }\r\n}\r\n```\r\n\r\n## Installation\r\n\r\n```bash\r\ndotnet new install Nall.ResultEndpoints.Template\r\n```\r\n\r\nVerify installation:\r\n\r\n```bash\r\ndotnet new list result-endpoints-api\r\n\r\n# These templates matched your input: 'result-endpoints-api'\r\n\r\n# Template Name     Short Name             Language  Tags\r\n# ----------------  ---------------------  --------  ----------------------------\r\n# Result Endpoints   -resultendpoints-api  [C#]      Web/API/Ardalis.ApiEndpoints\r\n```\r\n\r\n## Usage\r\n\r\n```bash\r\ndotnet new result-endpoints-api --dry-run\r\n\r\n# File actions would have been taken:\r\n#   Create: ./.vscode/settings.json\r\n#   Create: ./Data/DbContext.cs\r\n#   Create: ./Endpoints/HelloWorld.cs\r\n#   Create: ./Endpoints/Todo/CreateTodo.cs\r\n#   Create: ./Endpoints/Todo/DeleteTodo.cs\r\n#   Create: ./Endpoints/Todo/GetTodo.cs\r\n#   Create: ./Endpoints/Todo/ListTodos.cs\r\n#   Create: ./Endpoints/Todo/UpdateTodo.cs\r\n#   Create: ./HttpResultsOperationFilter.cs\r\n#   Create: ./Program.cs\r\n#   Create: ./Properties/launchSettings.json\r\n#   Create: ./Seeder.cs\r\n#   Create: ./appsettings.Development.json\r\n#   Create: ./appsettings.json\r\n#   Create: ./content.csproj\r\n```\r\n\r\n## Main takeaways\r\n\r\n* `TypedResults` directly contributes to OpenAPI. And the ancillary `Results` class describes discriminated unions for the response types.\r\n* `TypedResults` can be used in MVC Controllers and Minimal APIs.\r\n* `Ardalis.ApiEndpoints` is built on top of Controllers, therefore we can use it in conjunction with `TypedResults`.\r\n* `Ardales.ApiEndpoints` has two main classes: `EndpointBaseSync` and `EndpointBaseAsync`, both inherits from `ControllerBase`. It means that automatic model validation is enabled by default. This is why we need to extend generated OpenAPI definition with additional responses produced by model validation. I.e.: in API scenarios, we can add `ProblemDetails` as the way to report validation errors.\r\n* Another important aspect, is exception handling, although, it is not recommended to throw exceptions from client code, sometimes it is inevitable. In this case, exceptions are handled by global error handler. Exceptions are transformed into `ProblemDetails` and returned to the client.\r\n* We can use `EndpointSummary`, `EndpointDescription`, `EndpointName` to extend generated OpenAPI definition in library agnostic way.\r\n\r\n## References\r\n\r\n- \u003chttps://github.com/ardalis/ApiEndpoints\u003e\r\n- \u003chttps://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-8.0#problem-details\u003e\r\n- \u003chttps://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis/responses?view=aspnetcore-8.0\u003e\r\n- \u003chttps://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.typedresults?view=aspnetcore-8.0\u003e\r\n- \u003chttps://learn.microsoft.com/en-us/aspnet/core/web-api/handle-errors?view=aspnetcore-8.0#validation-failure-error-response\u003e\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikiforovall%2Fresult-endpoints-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnikiforovall%2Fresult-endpoints-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikiforovall%2Fresult-endpoints-template/lists"}