Skip to content

Commit fc7732d

Browse files
author
Chris Santero
committed
add IBaseUrlService
1 parent 25345f8 commit fc7732d

9 files changed

Lines changed: 75 additions & 17 deletions

File tree

JSONAPI.Autofac/JsonApiAutofacModule.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Autofac;
44
using JSONAPI.ActionFilters;
55
using JSONAPI.Core;
6+
using JSONAPI.Http;
67
using JSONAPI.Json;
78
using JSONAPI.Payload;
89
using JSONAPI.Payload.Builders;
@@ -36,6 +37,7 @@ protected override void Load(ContainerBuilder builder)
3637
}).As<IResourceTypeRegistry>().SingleInstance();
3738

3839
builder.RegisterType<JsonApiHttpConfiguration>();
40+
builder.RegisterType<BaseUrlService>().As<IBaseUrlService>();
3941

4042
// Serialization
4143
builder.RegisterType<MetadataSerializer>().As<IMetadataSerializer>().SingleInstance();

JSONAPI.EntityFramework/Http/EntityFrameworkPayloadMaterializer.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class EntityFrameworkPayloadMaterializer<T> : IPayloadMaterializer<T> whe
2323
private readonly IResourceTypeRegistry _resourceTypeRegistry;
2424
private readonly IQueryableResourceCollectionPayloadBuilder _queryableResourceCollectionPayloadBuilder;
2525
private readonly ISingleResourcePayloadBuilder _singleResourcePayloadBuilder;
26+
private readonly IBaseUrlService _baseUrlService;
2627
private readonly MethodInfo _getRelatedToManyMethod;
2728
private readonly MethodInfo _getRelatedToOneMethod;
2829

@@ -33,16 +34,19 @@ public class EntityFrameworkPayloadMaterializer<T> : IPayloadMaterializer<T> whe
3334
/// <param name="resourceTypeRegistry"></param>
3435
/// <param name="queryableResourceCollectionPayloadBuilder"></param>
3536
/// <param name="singleResourcePayloadBuilder"></param>
37+
/// <param name="baseUrlService"></param>
3638
public EntityFrameworkPayloadMaterializer(
3739
DbContext dbContext,
3840
IResourceTypeRegistry resourceTypeRegistry,
3941
IQueryableResourceCollectionPayloadBuilder queryableResourceCollectionPayloadBuilder,
40-
ISingleResourcePayloadBuilder singleResourcePayloadBuilder)
42+
ISingleResourcePayloadBuilder singleResourcePayloadBuilder,
43+
IBaseUrlService baseUrlService)
4144
{
4245
_dbContext = dbContext;
4346
_resourceTypeRegistry = resourceTypeRegistry;
4447
_queryableResourceCollectionPayloadBuilder = queryableResourceCollectionPayloadBuilder;
4548
_singleResourcePayloadBuilder = singleResourcePayloadBuilder;
49+
_baseUrlService = baseUrlService;
4650
_getRelatedToManyMethod = GetType()
4751
.GetMethod("GetRelatedToMany", BindingFlags.NonPublic | BindingFlags.Instance);
4852
_getRelatedToOneMethod = GetType()
@@ -116,11 +120,9 @@ public virtual async Task<IJsonApiPayload> DeleteRecord(string id, CancellationT
116120
/// <summary>
117121
/// Gets the base URL for link creation from the current request
118122
/// </summary>
119-
/// <param name="request"></param>
120-
/// <returns></returns>
121-
protected static string GetBaseUrlFromRequest(HttpRequestMessage request)
123+
protected string GetBaseUrlFromRequest(HttpRequestMessage request)
122124
{
123-
return new Uri(request.RequestUri.AbsoluteUri.Replace(request.RequestUri.PathAndQuery, String.Empty)).ToString();
125+
return _baseUrlService.GetBaseUrl(request);
124126
}
125127

126128
/// <summary>

JSONAPI.Tests/Payload/Builders/FallbackPayloadBuilderTests.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Web.Http.Controllers;
1010
using FluentAssertions;
1111
using JSONAPI.Core;
12+
using JSONAPI.Http;
1213
using JSONAPI.Payload;
1314
using JSONAPI.Payload.Builders;
1415
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -45,13 +46,12 @@ public async Task Creates_single_resource_payload_for_registered_non_collection_
4546
var cancellationTokenSource = new CancellationTokenSource();
4647

4748
var request = new HttpRequestMessage(HttpMethod.Get, "https://www.example.com/fruits");
48-
var mockRequestContext = new Mock<HttpRequestContext>();
49-
mockRequestContext.Setup(c => c.VirtualPathRoot).Returns("https://www.example.com/fruits");
50-
request.SetRequestContext(mockRequestContext.Object);
49+
var mockBaseUrlService = new Mock<IBaseUrlService>(MockBehavior.Strict);
50+
mockBaseUrlService.Setup(s => s.GetBaseUrl(request)).Returns("https://www.example.com");
5151

5252
// Act
5353
var fallbackPayloadBuilder = new FallbackPayloadBuilder(singleResourcePayloadBuilder.Object,
54-
mockQueryablePayloadBuilder.Object, mockResourceCollectionPayloadBuilder.Object);
54+
mockQueryablePayloadBuilder.Object, mockResourceCollectionPayloadBuilder.Object, mockBaseUrlService.Object);
5555
var resultPayload = await fallbackPayloadBuilder.BuildPayload(objectContent, request, cancellationTokenSource.Token);
5656

5757
// Assert
@@ -73,6 +73,9 @@ public async Task Creates_resource_collection_payload_for_queryables()
7373
var singleResourcePayloadBuilder = new Mock<ISingleResourcePayloadBuilder>(MockBehavior.Strict);
7474

7575
var request = new HttpRequestMessage();
76+
77+
var mockBaseUrlService = new Mock<IBaseUrlService>(MockBehavior.Strict);
78+
mockBaseUrlService.Setup(s => s.GetBaseUrl(request)).Returns("https://www.example.com/");
7679

7780
var cancellationTokenSource = new CancellationTokenSource();
7881

@@ -85,7 +88,7 @@ public async Task Creates_resource_collection_payload_for_queryables()
8588

8689
// Act
8790
var fallbackPayloadBuilder = new FallbackPayloadBuilder(singleResourcePayloadBuilder.Object,
88-
mockQueryablePayloadBuilder.Object, mockResourceCollectionPayloadBuilder.Object);
91+
mockQueryablePayloadBuilder.Object, mockResourceCollectionPayloadBuilder.Object, mockBaseUrlService.Object);
8992
var resultPayload = await fallbackPayloadBuilder.BuildPayload(items, request, cancellationTokenSource.Token);
9093

9194
// Assert
@@ -110,6 +113,9 @@ public async Task Creates_resource_collection_payload_for_non_queryable_enumerab
110113

111114
var request = new HttpRequestMessage(HttpMethod.Get, "https://www.example.com/fruits");
112115

116+
var mockBaseUrlService = new Mock<IBaseUrlService>(MockBehavior.Strict);
117+
mockBaseUrlService.Setup(s => s.GetBaseUrl(request)).Returns("https://www.example.com/");
118+
113119
var mockQueryablePayloadBuilder = new Mock<IQueryableResourceCollectionPayloadBuilder>(MockBehavior.Strict);
114120
var mockResourceCollectionPayloadBuilder = new Mock<IResourceCollectionPayloadBuilder>(MockBehavior.Strict);
115121
mockResourceCollectionPayloadBuilder
@@ -118,7 +124,7 @@ public async Task Creates_resource_collection_payload_for_non_queryable_enumerab
118124

119125
// Act
120126
var fallbackPayloadBuilder = new FallbackPayloadBuilder(singleResourcePayloadBuilder.Object,
121-
mockQueryablePayloadBuilder.Object, mockResourceCollectionPayloadBuilder.Object);
127+
mockQueryablePayloadBuilder.Object, mockResourceCollectionPayloadBuilder.Object, mockBaseUrlService.Object);
122128
var resultPayload = await fallbackPayloadBuilder.BuildPayload(items, request, cancellationTokenSource.Token);
123129

124130
// Assert

JSONAPI/Core/JsonApiConfiguration.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Web.Http;
22
using JSONAPI.ActionFilters;
3+
using JSONAPI.Http;
34
using JSONAPI.Json;
45
using JSONAPI.Payload;
56
using JSONAPI.Payload.Builders;
@@ -67,12 +68,14 @@ public void Apply(HttpConfiguration httpConfig)
6768
var paginationTransformer = new DefaultPaginationTransformer();
6869

6970
// Builders
71+
var baseUrlService = new BaseUrlService();
7072
var singleResourcePayloadBuilder = new RegistryDrivenSingleResourcePayloadBuilder(_resourceTypeRegistry, linkConventions);
7173
var resourceCollectionPayloadBuilder = new RegistryDrivenResourceCollectionPayloadBuilder(_resourceTypeRegistry, linkConventions);
7274
var queryableResourcePayloadBuilder = new DefaultQueryableResourceCollectionPayloadBuilder(resourceCollectionPayloadBuilder,
73-
queryableEnumerationTransformer, filteringTransformer, sortingTransformer, paginationTransformer);
75+
queryableEnumerationTransformer, filteringTransformer, sortingTransformer, paginationTransformer, baseUrlService);
7476
var errorPayloadBuilder = new ErrorPayloadBuilder();
75-
var fallbackPayloadBuilder = new FallbackPayloadBuilder(singleResourcePayloadBuilder, queryableResourcePayloadBuilder, resourceCollectionPayloadBuilder);
77+
var fallbackPayloadBuilder = new FallbackPayloadBuilder(singleResourcePayloadBuilder,
78+
queryableResourcePayloadBuilder, resourceCollectionPayloadBuilder, baseUrlService);
7679

7780
// Dependencies for JsonApiHttpConfiguration
7881
var formatter = new JsonApiFormatter(singleResourcePayloadSerializer, resourceCollectionPayloadSerializer, errorPayloadSerializer, errorPayloadBuilder);

JSONAPI/Http/BaseUrlService.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Net.Http;
3+
4+
namespace JSONAPI.Http
5+
{
6+
/// <summary>
7+
/// Default implementation of IBaseUrlService
8+
/// </summary>
9+
public class BaseUrlService : IBaseUrlService
10+
{
11+
public string GetBaseUrl(HttpRequestMessage requestMessage)
12+
{
13+
return
14+
new Uri(requestMessage.RequestUri.AbsoluteUri.Replace(requestMessage.RequestUri.PathAndQuery,
15+
String.Empty)).ToString();
16+
}
17+
}
18+
}

JSONAPI/Http/IBaseUrlService.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Net.Http;
2+
3+
namespace JSONAPI.Http
4+
{
5+
/// <summary>
6+
/// Service allowing you to get the base URL for a request
7+
/// </summary>
8+
public interface IBaseUrlService
9+
{
10+
/// <summary>
11+
/// Gets the base URL for a request
12+
/// </summary>
13+
string GetBaseUrl(HttpRequestMessage requestMessage);
14+
}
15+
}

JSONAPI/JSONAPI.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@
9393
<Compile Include="Extensions\QueryableExtensions.cs" />
9494
<Compile Include="Extensions\StringExtensions.cs" />
9595
<Compile Include="Extensions\TypeExtensions.cs" />
96+
<Compile Include="Http\BaseUrlService.cs" />
97+
<Compile Include="Http\IBaseUrlService.cs" />
9698
<Compile Include="Http\IPayloadMaterializer.cs" />
9799
<Compile Include="Http\JsonApiController.cs" />
98100
<Compile Include="Http\PascalizedControllerSelector.cs" />

JSONAPI/Payload/Builders/DefaultQueryableResourceCollectionPayloadBuilder.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Threading;
55
using System.Threading.Tasks;
66
using JSONAPI.ActionFilters;
7+
using JSONAPI.Http;
78

89
namespace JSONAPI.Payload.Builders
910
{
@@ -17,6 +18,7 @@ public class DefaultQueryableResourceCollectionPayloadBuilder : IQueryableResour
1718
private readonly IQueryableFilteringTransformer _filteringTransformer;
1819
private readonly IQueryableSortingTransformer _sortingTransformer;
1920
private readonly IQueryablePaginationTransformer _paginationTransformer;
21+
private readonly IBaseUrlService _baseUrlService;
2022

2123
/// <summary>
2224
///
@@ -26,18 +28,21 @@ public class DefaultQueryableResourceCollectionPayloadBuilder : IQueryableResour
2628
/// <param name="filteringTransformer"></param>
2729
/// <param name="sortingTransformer"></param>
2830
/// <param name="paginationTransformer"></param>
31+
/// <param name="baseUrlService"></param>
2932
public DefaultQueryableResourceCollectionPayloadBuilder(
3033
IResourceCollectionPayloadBuilder resourceCollectionPayloadBuilder,
3134
IQueryableEnumerationTransformer enumerationTransformer,
3235
IQueryableFilteringTransformer filteringTransformer,
3336
IQueryableSortingTransformer sortingTransformer,
34-
IQueryablePaginationTransformer paginationTransformer)
37+
IQueryablePaginationTransformer paginationTransformer,
38+
IBaseUrlService baseUrlService)
3539
{
3640
_resourceCollectionPayloadBuilder = resourceCollectionPayloadBuilder;
3741
_enumerationTransformer = enumerationTransformer;
3842
_filteringTransformer = filteringTransformer;
3943
_sortingTransformer = sortingTransformer;
4044
_paginationTransformer = paginationTransformer;
45+
_baseUrlService = baseUrlService;
4146
}
4247

4348
public async Task<IResourceCollectionPayload> BuildPayload<T>(IQueryable<T> query, HttpRequestMessage request, CancellationToken cancellationToken)
@@ -54,7 +59,7 @@ public async Task<IResourceCollectionPayload> BuildPayload<T>(IQueryable<T> quer
5459
query = paginationResults.PagedQuery;
5560
}
5661

57-
var linkBaseUrl = new Uri(request.RequestUri.AbsoluteUri.Replace(request.RequestUri.PathAndQuery, String.Empty)).ToString();
62+
var linkBaseUrl = _baseUrlService.GetBaseUrl(request);
5863

5964
var results = await _enumerationTransformer.Enumerate(query, cancellationToken);
6065
return _resourceCollectionPayloadBuilder.BuildPayload(results, linkBaseUrl, null, null);

JSONAPI/Payload/Builders/FallbackPayloadBuilder.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Reflection;
66
using System.Threading;
77
using System.Threading.Tasks;
8+
using JSONAPI.Http;
89

910
namespace JSONAPI.Payload.Builders
1011
{
@@ -16,6 +17,7 @@ public class FallbackPayloadBuilder : IFallbackPayloadBuilder
1617
private readonly ISingleResourcePayloadBuilder _singleResourcePayloadBuilder;
1718
private readonly IQueryableResourceCollectionPayloadBuilder _queryableResourceCollectionPayloadBuilder;
1819
private readonly IResourceCollectionPayloadBuilder _resourceCollectionPayloadBuilder;
20+
private readonly IBaseUrlService _baseUrlService;
1921
private readonly Lazy<MethodInfo> _openBuildPayloadFromQueryableMethod;
2022
private readonly Lazy<MethodInfo> _openBuildPayloadFromEnumerableMethod;
2123

@@ -25,13 +27,16 @@ public class FallbackPayloadBuilder : IFallbackPayloadBuilder
2527
/// <param name="singleResourcePayloadBuilder"></param>
2628
/// <param name="queryableResourceCollectionPayloadBuilder"></param>
2729
/// <param name="resourceCollectionPayloadBuilder"></param>
30+
/// <param name="baseUrlService"></param>
2831
public FallbackPayloadBuilder(ISingleResourcePayloadBuilder singleResourcePayloadBuilder,
2932
IQueryableResourceCollectionPayloadBuilder queryableResourceCollectionPayloadBuilder,
30-
IResourceCollectionPayloadBuilder resourceCollectionPayloadBuilder)
33+
IResourceCollectionPayloadBuilder resourceCollectionPayloadBuilder,
34+
IBaseUrlService baseUrlService)
3135
{
3236
_singleResourcePayloadBuilder = singleResourcePayloadBuilder;
3337
_queryableResourceCollectionPayloadBuilder = queryableResourceCollectionPayloadBuilder;
3438
_resourceCollectionPayloadBuilder = resourceCollectionPayloadBuilder;
39+
_baseUrlService = baseUrlService;
3540

3641
_openBuildPayloadFromQueryableMethod =
3742
new Lazy<MethodInfo>(
@@ -72,7 +77,7 @@ public async Task<IJsonApiPayload> BuildPayload(object obj, HttpRequestMessage r
7277
isCollection = true;
7378
}
7479

75-
var linkBaseUrl = new Uri(requestMessage.RequestUri.AbsoluteUri.Replace(requestMessage.RequestUri.PathAndQuery, String.Empty)).ToString();
80+
var linkBaseUrl = _baseUrlService.GetBaseUrl(requestMessage);
7681

7782
if (isCollection)
7883
{

0 commit comments

Comments
 (0)