Skip to content

Commit

Permalink
feat(dapi): add data api endpoint version to connection info (#372)
Browse files Browse the repository at this point in the history
Add the DataApi target version to the ConnectionInfo object
Use the target version to calculate the DataApi endpoints
  • Loading branch information
MichaelL79 authored Dec 9, 2024
1 parent 746d4bc commit 325bccb
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 7 deletions.
30 changes: 23 additions & 7 deletions src/FMData.Rest/FileMakerRestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public class FileMakerRestClient : FileMakerApiClientBase, IFileMakerRestClient

private readonly IAuthTokenProvider _authTokenProvider;
private readonly bool _useNewClientForContainers = false;
private readonly string _targetVersion = "v1";

#region Constructors
/// <summary>
Expand Down Expand Up @@ -98,6 +99,21 @@ public FileMakerRestClient(
{
_authTokenProvider = authTokenProvider;
_useNewClientForContainers = useNewClientForContainers;
switch (_authTokenProvider.ConnectionInfo?.RestTargetVersion)
{
case RestTargetVersion.v1:
_targetVersion = "v1";
break;
case RestTargetVersion.v2:
_targetVersion = "v2";
break;
case RestTargetVersion.vLatest:
_targetVersion = "vLatest";
break;
default:
_targetVersion = "v1";
break;
}
#if NETSTANDARD1_3
var header = new System.Net.Http.Headers.ProductHeaderValue("FMData.Rest", "4");
var userAgent = new System.Net.Http.Headers.ProductInfoHeaderValue(header);
Expand All @@ -116,7 +132,7 @@ public FileMakerRestClient(
/// <summary>
/// Note we assume _fmsUri has no trailing slash as its cut off in the constructor.
/// </summary>
private string BaseEndPoint => $"{FmsUri}/fmi/data/v1/databases/{FileName}";
private string BaseEndPoint => $"{FmsUri}/fmi/data/{_targetVersion}/databases/{FileName}";

/// <summary>
/// Generate the appropriate Authentication endpoint uri for this instance of the data client.
Expand Down Expand Up @@ -639,7 +655,7 @@ public override async Task<string> RunScriptAsync(string layout, string script,
await UpdateTokenDateAsync().ConfigureAwait(false); // we're about to use the token so update date used

// generate request url
var uri = $"{FmsUri}/fmi/data/v1"
var uri = $"{FmsUri}/fmi/data/{_targetVersion}"
+ $"/databases/{Uri.EscapeDataString(FileName)}"
+ $"/layouts/{Uri.EscapeDataString(layout)}"
+ $"/script/{Uri.EscapeDataString(script)}";
Expand Down Expand Up @@ -835,7 +851,7 @@ public override async Task<IResponse> SetGlobalFieldAsync(string baseTable, stri
public override async Task<ProductInformation> GetProductInformationAsync()
{
// generate request url
var requestMessage = new HttpRequestMessage(HttpMethod.Get, $"{FmsUri}/fmi/data/v1/productinfo");
var requestMessage = new HttpRequestMessage(HttpMethod.Get, $"{FmsUri}/fmi/data/{_targetVersion}/productinfo");

// run the patch action
var response = await Client.SendAsync(requestMessage).ConfigureAwait(false);
Expand Down Expand Up @@ -869,7 +885,7 @@ public override async Task<IReadOnlyCollection<string>> GetDatabasesAsync()
// don't need to refresh the token, because this is a basic authentication request

// generate request url
var requestMessage = new HttpRequestMessage(HttpMethod.Get, $"{FmsUri}/fmi/data/v1/databases");
var requestMessage = new HttpRequestMessage(HttpMethod.Get, $"{FmsUri}/fmi/data/{_targetVersion}/databases");

// special non-token auth to list databases
requestMessage.Headers.Authorization = await _authTokenProvider.GetAuthenticationHeaderValue().ConfigureAwait(false);
Expand Down Expand Up @@ -906,7 +922,7 @@ public override async Task<IReadOnlyCollection<LayoutListItem>> GetLayoutsAsync(
await UpdateTokenDateAsync().ConfigureAwait(false); // we're about to use the token so update date used

// generate request url
var uri = $"{FmsUri}/fmi/data/v1/"
var uri = $"{FmsUri}/fmi/data/{_targetVersion}/"
+ $"databases/{Uri.EscapeDataString(FileName)}/layouts";
var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);

Expand Down Expand Up @@ -945,7 +961,7 @@ public override async Task<IReadOnlyCollection<ScriptListItem>> GetScriptsAsync(
await UpdateTokenDateAsync().ConfigureAwait(false); // we're about to use the token so update date used

// generate request url
var uri = $"{FmsUri}/fmi/data/v1"
var uri = $"{FmsUri}/fmi/data/{_targetVersion}"
+ $"/databases/{Uri.EscapeDataString(FileName)}/scripts";
var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);

Expand Down Expand Up @@ -986,7 +1002,7 @@ public override async Task<LayoutMetadata> GetLayoutAsync(string layout, int? re
await UpdateTokenDateAsync().ConfigureAwait(false); // we're about to use the token so update date used

// generate request url
var uri = $"{FmsUri}/fmi/data/v1"
var uri = $"{FmsUri}/fmi/data/{_targetVersion}"
+ $"/databases/{Uri.EscapeDataString(FileName)}"
+ $"/layouts/{Uri.EscapeDataString(layout)}";
if (recordId.HasValue)
Expand Down
4 changes: 4 additions & 0 deletions src/FMData/ConnectionInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ public class ConnectionInfo
/// Password to use when making the connection.
/// </summary>
public string Password { get; set; }
/// <summary>
/// Gets or sets the <see cref="RestTargetVersion"/> to use.
/// </summary>
public RestTargetVersion? RestTargetVersion { get; set; }

#region FileMaker Cloud

Expand Down
21 changes: 21 additions & 0 deletions src/FMData/RestTargetVersion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace FMData
{
/// <summary>
/// All supported FileMaker DataAPI endpoint versions.
/// </summary>
public enum RestTargetVersion
{
/// <summary>
/// Uses v1 endpoint of the DataAPI.
/// </summary>
v1,
/// <summary>
/// Uses v2 endpoint of the DataAPI.
/// </summary>
v2,
/// <summary>
/// Uses the latest endpoint version of the DataAPI.
/// </summary>
vLatest
}
}
74 changes: 74 additions & 0 deletions tests/FMData.Rest.Tests/GeneralTests.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Runtime.Serialization;
using System.Threading.Tasks;
using FMData.Rest.Requests;
using FMData.Rest.Tests.TestModels;
using Newtonsoft.Json.Linq;
using RichardSzalay.MockHttp;
using Xunit;

Expand Down Expand Up @@ -197,5 +199,77 @@ public async Task Test_DateTime_To_Timestamp_Parsing()
var responseDataContainsResult = response.Any(r => r.Created == DateTime.ParseExact("03/29/2018 15:22:09", "MM/dd/yyyy HH:mm:ss", CultureInfo.InvariantCulture));
Assert.True(responseDataContainsResult);
}


[Fact]
public void Test_EndpointVersion_Default()
{
// arrange
var expected = "http://localhost/fmi/data/v1/databases/test-file/sessions";
var testClients = CreateEndpointTestClients(null);

// assert
foreach (var client in testClients)
{
Assert.Equal(expected, client.AuthEndpoint());
}
}

[Fact]
public void Test_EndpointVersion_v1()
{
// arrange
var expected = "http://localhost/fmi/data/v1/databases/test-file/sessions";
var testClients = CreateEndpointTestClients(RestTargetVersion.v1);

// assert
foreach (var client in testClients)
{
Assert.Equal(expected, client.AuthEndpoint());
}
}

[Fact]
public void Test_EndpointVersion_v2()
{
// arrange
var expected = "http://localhost/fmi/data/v2/databases/test-file/sessions";
var testClients = CreateEndpointTestClients(RestTargetVersion.v2);

// assert
foreach (var client in testClients)
{
Assert.Equal(expected, client.AuthEndpoint());
}
}

[Fact]
public void Test_EndpointVersion_vLatest()
{
// arrange
var expected = "http://localhost/fmi/data/vLatest/databases/test-file/sessions";
var testClients = CreateEndpointTestClients(RestTargetVersion.vLatest);

// assert
foreach (var client in testClients)
{
Assert.Equal(expected, client.AuthEndpoint());
}
}

private IEnumerable<FileMakerRestClient> CreateEndpointTestClients(RestTargetVersion? targetVersion)
{
var mockHttp = new MockHttpMessageHandler();
var server = "http://localhost";
var file = "test-file";
var user = "unit";
var pass = "test";
var connectionInfo = new ConnectionInfo { FmsUri = server, Database = file, Username = user, Password = pass, RestTargetVersion = targetVersion };

return [
new(mockHttp.ToHttpClient(), connectionInfo),
new(mockHttp.ToHttpClient(), new DefaultAuthTokenProvider(connectionInfo))
];
}
}
}

0 comments on commit 325bccb

Please sign in to comment.