Skip to content

Commit

Permalink
added get single link endpoint and refactored swagger documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
asser-dk committed Oct 31, 2017
1 parent afe6d8d commit 70edcb6
Show file tree
Hide file tree
Showing 14 changed files with 142 additions and 10 deletions.
28 changes: 28 additions & 0 deletions Fenris.Validation/ArgumentValidation/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace Fenris.Validation.ArgumentValidation
{
using System;
using JetBrains.Annotations;

[PublicAPI]
public static class StringExtensions
{
[AssertionMethod]
public static void ShouldNotBeNullOrEmpty(
[AssertionCondition(AssertionConditionType.IS_NOT_NULL)] this string stringToValidate,
string errorMessage = null,
[InvokerParameterName] string paramName = null)
{
errorMessage = errorMessage ?? "String cannot be null or empty.";

if (stringToValidate == null)
{
throw new ArgumentNullException(paramName, errorMessage);
}

if (string.IsNullOrEmpty(stringToValidate))
{
throw new ArgumentException(errorMessage, paramName);
}
}
}
}
11 changes: 11 additions & 0 deletions Fenris.Validation/Fenris.Validation.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="jetbrains.annotations" Version="11.1.0" />
</ItemGroup>

</Project>
7 changes: 7 additions & 0 deletions PrettyLink.Api/ComplexTypes/Error.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace PrettyLink.Api.ComplexTypes
{
public class Error
{
public string Message { get; set; }
}
}
46 changes: 44 additions & 2 deletions PrettyLink.Api/Controllers/LinkController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using Fenris.Validation.ArgumentValidation;
using Microsoft.AspNetCore.Mvc;
using PrettyLink.Api.ComplexTypes;
using PrettyLink.Domain.Services;
Expand All @@ -20,14 +21,55 @@ public LinkController(ILinkService service)
/// <summary>
/// Returns a list of all pretty links and their redirects
/// </summary>
/// <response code="200">Links are returned successfully</response>
[HttpGet("v1/links")]
[Produces("application/json")]
[ProducesResponseType(typeof(Link), 200)]
[ProducesResponseType(typeof(IEnumerable<Link>), 200)]
public async Task<IActionResult> GetLinksAsync()
{
var links = await service.GetLinksAsync().ConfigureAwait(false);

return Ok(Mapper.Map<IEnumerable<DomainLink>, IEnumerable<Link>>(links));
}

/// <summary>
/// Returns a single link.
/// </summary>
/// <param name="prettyLink">The link to return</param>
/// <response code="200">The link is returned successfully</response>
/// <response code="404">If the link could not be found</response>
[HttpGet("v1/links/{prettyLink}")]
[ProducesResponseType(typeof(Link), 200)]
[ProducesResponseType(typeof(Error), 404)]
public async Task<IActionResult> GetLinkAsync(string prettyLink)
{
prettyLink = prettyLink?.Trim();
prettyLink.ShouldNotBeNullOrEmpty(nameof(prettyLink));

var link = await service.GetLinkAsync(prettyLink).ConfigureAwait(false);

if (link == null)
{
return NotFound(new { Message = "Link not found." });
}

return Ok(Mapper.Map<DomainLink, Link>(link));
}

[ApiExplorerSettings(IgnoreApi = true)]
[HttpGet("/{prettyLink}")]
public async Task<IActionResult> RedirectToLink(string prettyLink)
{
prettyLink = prettyLink?.Trim();
prettyLink.ShouldNotBeNullOrEmpty(nameof(prettyLink));

var link = await service.GetLinkAsync(prettyLink).ConfigureAwait(false);

if (link == null)
{
return NotFound(new { Message = "Link not found." });
}

return RedirectPermanent(link.OriginalLink);
}
}
}
1 change: 1 addition & 0 deletions PrettyLink.Api/PrettyLink.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Fenris.Validation\Fenris.Validation.csproj" />
<ProjectReference Include="..\PrettyLink.Domain\PrettyLink.Domain.csproj" />
</ItemGroup>

Expand Down
3 changes: 2 additions & 1 deletion PrettyLink.Api/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using JetBrains.Annotations;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.PlatformAbstractions;
Expand Down Expand Up @@ -43,7 +44,7 @@ public void ConfigureServices(IServiceCollection services)
{
services.AddDomainServices();

services.AddMvc();
services.AddMvc(c => c.Filters.Add(new ProducesAttribute("application/json")));

services.AddSwaggerGen(
setup =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
</ItemGroup>

</Project>
6 changes: 3 additions & 3 deletions PrettyLink.Domain.UnitTest/PrettyLink.Domain.UnitTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions PrettyLink.Domain/DataAccess/ILinkDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ public interface ILinkDataProvider
[NotNull]
[ItemNotNull]
Task<IEnumerable<Link>> GetLinksAsync();

[NotNull]
[ItemCanBeNull]
Task<Link> GetLinkAsync([NotNull] string prettyLink);
}
}
8 changes: 8 additions & 0 deletions PrettyLink.Domain/DataAccess/LinkDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,13 @@ public async Task<IEnumerable<Link>> GetLinksAsync()
return await asyncSearch.GetRemainingAsync().ConfigureAwait(false);
}
}

public async Task<Link> GetLinkAsync(string prettyLink)
{
using (var context = new DynamoDBContext(new AmazonDynamoDBClient(new AmazonDynamoDBConfig())))
{
return await context.LoadAsync<Link>(prettyLink).ConfigureAwait(false);
}
}
}
}
4 changes: 4 additions & 0 deletions PrettyLink.Domain/PrettyLink.Domain.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@
<PackageReference Include="jetbrains.annotations" Version="11.1.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Fenris.Validation\Fenris.Validation.csproj" />
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions PrettyLink.Domain/Services/ILinkService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

public interface ILinkService
{
[NotNull]
[ItemCanBeNull]
Task<Link> GetLinkAsync([NotNull] string prettyLink);

[NotNull]
[ItemNotNull]
Task<IEnumerable<Link>> GetLinksAsync();
Expand Down
8 changes: 8 additions & 0 deletions PrettyLink.Domain/Services/LinkService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
using System.Collections.Generic;
using System.Threading.Tasks;
using Fenris.Validation.ArgumentValidation;
using JetBrains.Annotations;
using PrettyLink.Domain.DataAccess;
using PrettyLink.Domain.DataAccess.Model;
Expand All @@ -16,6 +17,13 @@ public LinkService(ILinkDataProvider dataProvider)
this.dataProvider = dataProvider;
}

public async Task<Link> GetLinkAsync(string prettyLink)
{
prettyLink.ShouldNotBeNullOrEmpty(nameof(prettyLink));

return await dataProvider.GetLinkAsync(prettyLink).ConfigureAwait(false);
}

public async Task<IEnumerable<Link>> GetLinksAsync()
{
return await dataProvider.GetLinksAsync().ConfigureAwait(false);
Expand Down
16 changes: 15 additions & 1 deletion PrettyLink.sln
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2005
VisualStudioVersion = 15.0.27004.2006
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PrettyLink.Api", "PrettyLink.Api\PrettyLink.Api.csproj", "{DFCD3241-5EB1-47C0-8FCC-1E62010B55DB}"
EndProject
Expand All @@ -16,6 +16,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fenris.Validation", "Fenris.Validation\Fenris.Validation.csproj", "{7FA6103C-2093-4FF8-8931-D908F593833C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -74,6 +76,18 @@ Global
{96DEA9CF-5B0F-4244-B299-E4E93AF45C35}.Release|x64.Build.0 = Release|Any CPU
{96DEA9CF-5B0F-4244-B299-E4E93AF45C35}.Release|x86.ActiveCfg = Release|Any CPU
{96DEA9CF-5B0F-4244-B299-E4E93AF45C35}.Release|x86.Build.0 = Release|Any CPU
{7FA6103C-2093-4FF8-8931-D908F593833C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7FA6103C-2093-4FF8-8931-D908F593833C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7FA6103C-2093-4FF8-8931-D908F593833C}.Debug|x64.ActiveCfg = Debug|Any CPU
{7FA6103C-2093-4FF8-8931-D908F593833C}.Debug|x64.Build.0 = Debug|Any CPU
{7FA6103C-2093-4FF8-8931-D908F593833C}.Debug|x86.ActiveCfg = Debug|Any CPU
{7FA6103C-2093-4FF8-8931-D908F593833C}.Debug|x86.Build.0 = Debug|Any CPU
{7FA6103C-2093-4FF8-8931-D908F593833C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7FA6103C-2093-4FF8-8931-D908F593833C}.Release|Any CPU.Build.0 = Release|Any CPU
{7FA6103C-2093-4FF8-8931-D908F593833C}.Release|x64.ActiveCfg = Release|Any CPU
{7FA6103C-2093-4FF8-8931-D908F593833C}.Release|x64.Build.0 = Release|Any CPU
{7FA6103C-2093-4FF8-8931-D908F593833C}.Release|x86.ActiveCfg = Release|Any CPU
{7FA6103C-2093-4FF8-8931-D908F593833C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit 70edcb6

Please sign in to comment.