Skip to content

Commit

Permalink
add endpoint naming convention
Browse files Browse the repository at this point in the history
  • Loading branch information
dasiths committed Mar 15, 2020
1 parent 409de10 commit 16948c4
Show file tree
Hide file tree
Showing 21 changed files with 177 additions and 98 deletions.
File renamed without changes.
3 changes: 3 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ jobs:
- name: Build with dotnet
run: dotnet build --configuration Release
working-directory: ./src
- name: Test with dotnet
run: dotnet test
working-directory: ./src
- name: Create the package
run: dotnet pack --configuration Release SimpleEndPoints
working-directory: ./src
Expand Down
File renamed without changes.
23 changes: 23 additions & 0 deletions src/SimpleEndPoints/Conventions/EndpointRoutingConvention.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Microsoft.AspNetCore.Mvc.ApplicationModels;

namespace SimpleEndpoints.Conventions
{
public class EndpointRoutingConvention: IApplicationModelConvention
{
private const string EndpointString = "endpoint";

public void Apply(ApplicationModel application)
{
foreach (var controller in application.Controllers)
{
controller.Selectors[0].AttributeRouteModel.Template = controller
.Selectors[0]
.AttributeRouteModel
.Template
.Replace($"[{EndpointString}]",
controller.ControllerName.Substring(0,
controller.ControllerName.Length - EndpointString.Length));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,64 @@
namespace SimpleEndpoints.Core
{
[ApiController]
[Route("[controller]")]
public abstract class AsyncEndpointController : ControllerBase
[Route("[endpoint]")]
public abstract class AsyncEndpoint : ControllerBase
{
[NonAction]
protected abstract Task<IActionResult> HandleAsync(CancellationToken cancellationToken = default);
}

[ApiController]
[Route("[controller]")]
public abstract class AsyncEndpointControllerWithRequest<TRequest> : ControllerBase
[Route("[endpoint]")]
public abstract class AsyncEndpointWithRequest<TRequest> : ControllerBase
{
[NonAction]
protected abstract Task<IActionResult> HandleAsync(TRequest requestModel, CancellationToken cancellationToken = default);
}

[ApiController]
[Route("[controller]")]
public abstract class AsyncEndpointController<TResponse> : ControllerBase
[Route("[endpoint]")]
public abstract class AsyncEndpoint<TResponse> : ControllerBase
{
[NonAction]
protected abstract Task<ActionResult<TResponse>> HandleAsync(CancellationToken cancellationToken = default);
}

[ApiController]
[Route("[controller]")]
public abstract class AsyncEndpointController<TRequest, TResponse> : ControllerBase
[Route("[endpoint]")]
public abstract class AsyncEndpoint<TRequest, TResponse> : ControllerBase
{
[NonAction]
protected abstract Task<ActionResult<TResponse>> HandleAsync(TRequest requestModel, CancellationToken cancellationToken = default);
}

[ApiController]
[Route("[controller]")]
public abstract class EndpointController : ControllerBase
[Route("[endpoint]")]
public abstract class Endpoint : ControllerBase
{
[NonAction]
protected abstract IActionResult Handle();
}

[ApiController]
[Route("[controller]")]
public abstract class EndpointControllerWithRequest<TRequest> : ControllerBase
[Route("[endpoint]")]
public abstract class EndpointWithRequest<TRequest> : ControllerBase
{
[NonAction]
protected abstract IActionResult Handle(TRequest requestModel);
}

[ApiController]
[Route("[controller]")]
public abstract class EndpointController<TResponse> : ControllerBase
[Route("[endpoint]")]
public abstract class Endpoint<TResponse> : ControllerBase
{
[NonAction]
protected abstract ActionResult<TResponse> Handle();
}

[ApiController]
[Route("[controller]")]
public abstract class EndpointController<TRequest, TResponse> : ControllerBase
[Route("[endpoint]")]
public abstract class Endpoint<TRequest, TResponse> : ControllerBase
{
[NonAction]
protected abstract ActionResult<TResponse> Handle(TRequest requestModel);
Expand Down
16 changes: 16 additions & 0 deletions src/SimpleEndPoints/Extensions/MvcOptionsExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Mvc;
using SimpleEndpoints.Conventions;

namespace SimpleEndpoints.Extensions
{
public static class MvcOptionsExtensions
{
public static void AddEndpointRoutingConvention(this MvcOptions options)
{
options.Conventions.Add(new EndpointRoutingConvention());
}
}
}
2 changes: 1 addition & 1 deletion src/SimpleEndPoints/SimpleEndpoints.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<RepositoryUrl>https://github.com/dasiths/SimpleEndpoints</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<PackageTags>aspnetcore api controller endpoints</PackageTags>
<Version>1.0.1</Version>
<Version>1.0.2</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,32 @@

namespace SimpleEndpoints.VerbScoped
{
[ApiController]
[Route("[controller]")]
public abstract class AsyncDeleteEndpointController<TRequest> : AsyncEndpointControllerWithRequest<TRequest>

public abstract class AsyncDeleteEndpoint<TRequest> : AsyncEndpointWithRequest<TRequest>
{
[HttpDelete]
public virtual Task<IActionResult> Delete(TRequest model, CancellationToken cancellationToken = default) =>
HandleAsync(model, cancellationToken);
}

[ApiController]
[Route("[controller]")]
public abstract class AsyncDeleteEndpointController<TRequest, TResponse> : AsyncEndpointController<TRequest, TResponse>
public abstract class AsyncDeleteEndpoint<TRequest, TResponse> : AsyncEndpoint<TRequest, TResponse>
{
[HttpDelete]
public virtual Task<ActionResult<TResponse>> Delete(TRequest model, CancellationToken cancellationToken = default) =>
HandleAsync(model, cancellationToken);
}

[ApiController]
[Route("[controller]")]
public abstract class DeleteEndpointController<TRequest> : EndpointControllerWithRequest<TRequest>
public abstract class DeleteEndpoint<TRequest> : EndpointWithRequest<TRequest>
{
[HttpDelete]
public virtual IActionResult Delete(TRequest model) =>
Handle(model);
}

[ApiController]
[Route("[controller]")]
public abstract class DeleteEndpointController<TRequest, TResponse> : EndpointController<TRequest, TResponse>
public abstract class DeleteEndpoint<TRequest, TResponse> : Endpoint<TRequest, TResponse>
{
[HttpDelete]
public virtual ActionResult<TResponse> Delete(TRequest model) =>
Handle(model);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,76 +5,60 @@

namespace SimpleEndpoints.VerbScoped
{
[ApiController]
[Route("[controller]")]
public abstract class AsyncGetEndpointController : AsyncEndpointController

public abstract class AsyncGetEndpoint : AsyncEndpoint
{
[HttpGet]
public virtual Task<IActionResult> Get(CancellationToken cancellationToken = default) =>
HandleAsync(cancellationToken);
}

[ApiController]
[Route("[controller]")]
public abstract class AsyncGetEndpointControllerWithRequest<TRequest> : AsyncEndpointControllerWithRequest<TRequest>
public abstract class AsyncGetEndpointWithRequest<TRequest> : AsyncEndpointWithRequest<TRequest>
{
[HttpGet]
public virtual Task<IActionResult> Get(TRequest model, CancellationToken cancellationToken = default) =>
HandleAsync(model, cancellationToken);
}

[ApiController]
[Route("[controller]")]
public abstract class AsyncGetEndpointController<TResponse> : AsyncEndpointController<TResponse>
public abstract class AsyncGetEndpoint<TResponse> : AsyncEndpoint<TResponse>
{
[HttpGet]
public virtual Task<ActionResult<TResponse>> Get(CancellationToken cancellationToken = default) =>
HandleAsync(cancellationToken);
}

[ApiController]
[Route("[controller]")]
public abstract class AsyncGetEndpointController<TRequest, TResponse> : AsyncEndpointController<TRequest, TResponse>
public abstract class AsyncGetEndpoint<TRequest, TResponse> : AsyncEndpoint<TRequest, TResponse>
{
[HttpGet]
public virtual Task<ActionResult<TResponse>> Get(TRequest model, CancellationToken cancellationToken = default) =>
HandleAsync(model, cancellationToken);
}

[ApiController]
[Route("[controller]")]
public abstract class GetEndpointController : EndpointController
public abstract class GetEndpoint : Endpoint
{
[HttpGet]
public virtual IActionResult Get() =>
Handle();
}

[ApiController]
[Route("[controller]")]
public abstract class GetEndpointController<TResponse> : EndpointController<TResponse>
public abstract class GetEndpoint<TResponse> : Endpoint<TResponse>
{
[HttpGet]
public virtual ActionResult<TResponse> Get() =>
Handle();
}

[ApiController]
[Route("[controller]")]
public abstract class GetEndpointControllerWithRequest<TRequest> : EndpointControllerWithRequest<TRequest>
public abstract class GetEndpointWithRequest<TRequest> : EndpointWithRequest<TRequest>
{
[HttpGet]
public virtual IActionResult Get(TRequest model) =>
Handle(model);
}

[ApiController]
[Route("[controller]")]
public abstract class GetEndpointController<TRequest, TResponse> : EndpointController<TRequest, TResponse>
public abstract class GetEndpoint<TRequest, TResponse> : Endpoint<TRequest, TResponse>
{
[HttpGet]
public virtual ActionResult<TResponse> Get(TRequest model) =>
Handle(model);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,32 @@

namespace SimpleEndpoints.VerbScoped
{
[ApiController]
[Route("[controller]")]
public abstract class AsyncPostEndpointController<TRequest> : AsyncEndpointControllerWithRequest<TRequest>

public abstract class AsyncPostEndpoint<TRequest> : AsyncEndpointWithRequest<TRequest>
{
[HttpPost]
public virtual Task<IActionResult> Post(TRequest model, CancellationToken cancellationToken = default) =>
HandleAsync(model, cancellationToken);
}

[ApiController]
[Route("[controller]")]
public abstract class AsyncPostEndpointController<TRequest, TResponse> : AsyncEndpointController<TRequest, TResponse>
public abstract class AsyncPostEndpoint<TRequest, TResponse> : AsyncEndpoint<TRequest, TResponse>
{
[HttpPost]
public virtual Task<ActionResult<TResponse>> Post(TRequest model, CancellationToken cancellationToken = default) =>
HandleAsync(model, cancellationToken);
}

[ApiController]
[Route("[controller]")]
public abstract class PostEndpointController<TRequest> : EndpointControllerWithRequest<TRequest>
public abstract class PostEndpoint<TRequest> : EndpointWithRequest<TRequest>
{
[HttpPost]
public virtual IActionResult Post(TRequest model) =>
Handle(model);
}

[ApiController]
[Route("[controller]")]
public abstract class PostEndpointController<TRequest, TResponse> : EndpointController<TRequest, TResponse>
public abstract class PostEndpoint<TRequest, TResponse> : Endpoint<TRequest, TResponse>
{
[HttpPost]
public virtual ActionResult<TResponse> Post(TRequest model) =>
Handle(model);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,32 @@

namespace SimpleEndpoints.VerbScoped
{
[ApiController]
[Route("[controller]")]
public abstract class AsyncPutEndpointController<TRequest> : AsyncEndpointControllerWithRequest<TRequest>

public abstract class AsyncPutEndpoint<TRequest> : AsyncEndpointWithRequest<TRequest>
{
[HttpPut]
public virtual Task<IActionResult> Put(TRequest model, CancellationToken cancellationToken = default) =>
HandleAsync(model, cancellationToken);
}

[ApiController]
[Route("[controller]")]
public abstract class AsyncPutEndpointController<TRequest, TResponse> : AsyncEndpointController<TRequest, TResponse>

public abstract class AsyncPutEndpoint<TRequest, TResponse> : AsyncEndpoint<TRequest, TResponse>
{
[HttpPut]
public virtual Task<ActionResult<TResponse>> Put(TRequest model, CancellationToken cancellationToken = default) =>
HandleAsync(model, cancellationToken);
}

[ApiController]
[Route("[controller]")]
public abstract class PutEndpointController<TRequest> : EndpointControllerWithRequest<TRequest>

public abstract class PutEndpoint<TRequest> : EndpointWithRequest<TRequest>
{
[HttpPut]
public virtual IActionResult Put(TRequest model) =>
Handle(model);
}

[ApiController]
[Route("[controller]")]
public abstract class PutEndpointController<TRequest, TResponse> : EndpointController<TRequest, TResponse>

public abstract class PutEndpoint<TRequest, TResponse> : Endpoint<TRequest, TResponse>
{
[HttpPut]
public virtual ActionResult<TResponse> Put(TRequest model) =>
Handle(model);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

namespace SimpleEndpoints.Example.Models
namespace SimpleEndpoints.Example.Endpoints.SimpleMessage
{
public class SimpleMessage
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using SimpleEndpoints.Example.Models;
using SimpleEndpoints.VerbScoped;

namespace SimpleEndpoints.Example.Controllers
namespace SimpleEndpoints.Example.Endpoints.SimpleMessage
{
public class SimpleMessageController : AsyncPostEndpointController<SimpleMessage, SimpleResponse>
public class SimpleMessageEndpoint : AsyncPostEndpoint<SimpleMessage, SimpleResponse>
{
// Override if you want to change the default behaviour such as model binding
// Here we force it to use the [FromQuery] model binding instead of the default [FromBody] and define a custom Route
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace SimpleEndpoints.Example.Models
namespace SimpleEndpoints.Example.Endpoints.SimpleMessage
{
public class SimpleResponse
{
Expand Down
Loading

0 comments on commit 16948c4

Please sign in to comment.