Skip to content

Adds support for free-format client-generated IDs #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Examples/GettingStarted/Models/Book.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace GettingStarted.Models
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class Book : MongoIdentifiable
public sealed class Book : MongoObjectIdentifiable
{
[Attr]
public string Title { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace JsonApiDotNetCoreMongoDbExample.Models
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class TodoItem : MongoIdentifiable
public sealed class TodoItem : MongoObjectIdentifiable
{
[Attr]
public string Description { get; set; }
Expand Down
11 changes: 11 additions & 0 deletions src/JsonApiDotNetCore.MongoDb/Resources/IMongoIdentifiable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using JsonApiDotNetCore.Resources;

namespace JsonApiDotNetCore.MongoDb.Resources
{
/// <summary>
/// Marker interface to indicate a resource that is stored in MongoDB.
/// </summary>
public interface IMongoIdentifiable : IIdentifiable<string>
{
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
using JsonApiDotNetCore.Resources;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace JsonApiDotNetCore.MongoDb.Resources
{
/// <summary>
/// A convenient basic implementation of <see cref="IIdentifiable" /> for use with MongoDB models.
/// Basic implementation of a JSON:API resource whose Id is stored as a 12-byte hexadecimal ObjectId in MongoDB.
/// </summary>
public abstract class MongoIdentifiable : IIdentifiable<string>
public abstract class MongoObjectIdentifiable : IMongoIdentifiable
{
/// <inheritdoc />
[BsonId]
Expand Down
28 changes: 28 additions & 0 deletions src/JsonApiDotNetCore.MongoDb/Resources/MongoStringIdentifiable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson.Serialization.IdGenerators;

namespace JsonApiDotNetCore.MongoDb.Resources
{
/// <summary>
/// Basic implementation of a JSON:API resource whose Id is stored as a free-format string in MongoDB. Intended for resources that are created using
/// client-generated IDs.
/// </summary>
public abstract class MongoStringIdentifiable : IMongoIdentifiable
{
/// <inheritdoc />
[BsonId(IdGenerator = typeof(StringObjectIdGenerator))]
public virtual string Id { get; set; }

/// <inheritdoc />
[BsonIgnore]
public string StringId
{
get => Id;
set => Id = value;
}

/// <inheritdoc />
[BsonIgnore]
public string LocalId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.MongoDb.Resources;
using JsonApiDotNetCore.Queries;
Expand All @@ -22,7 +22,7 @@ public IgnoreRelationshipsResponseResourceObjectBuilder(ILinkBuilder linkBuilder
/// <inheritdoc />
protected override RelationshipEntry GetRelationshipData(RelationshipAttribute relationship, IIdentifiable resource)
{
if (resource is MongoIdentifiable)
if (resource is IMongoIdentifiable)
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public async Task Can_create_resource_with_client_generated_string_ID_having_sid
{
// Arrange
TextLanguage newLanguage = _fakers.TextLanguage.Generate();
newLanguage.Id = "507f191e810c19729de860ea";
newLanguage.Id = "free-format-client-generated-id";

await _testContext.RunOnDatabaseAsync(async db =>
{
Expand Down Expand Up @@ -88,7 +88,7 @@ public async Task Can_create_resource_with_client_generated_string_ID_having_no_
{
// Arrange
MusicTrack newTrack = _fakers.MusicTrack.Generate();
newTrack.Id = "5ffcc0d1d69a27c92b8c62dd";
newTrack.Id = "free-format-client-generated-id";

await _testContext.RunOnDatabaseAsync(async db =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.AtomicOperations
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class Lyric : MongoIdentifiable
public sealed class Lyric : MongoObjectIdentifiable
{
[Attr]
public string Format { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.AtomicOperations
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class MusicTrack : MongoIdentifiable
public sealed class MusicTrack : MongoStringIdentifiable
{
[RegularExpression(@"(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$")]
public override string Id { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.AtomicOperations
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class Performer : MongoIdentifiable
public sealed class Performer : MongoObjectIdentifiable
{
[Attr]
public string ArtistName { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.AtomicOperations
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class Playlist : MongoIdentifiable
public sealed class Playlist : MongoObjectIdentifiable
{
[Attr]
[Required]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.AtomicOperations
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class RecordCompany : MongoIdentifiable
public sealed class RecordCompany : MongoObjectIdentifiable
{
[Attr]
public string Name { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.AtomicOperations
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class TextLanguage : MongoIdentifiable
public sealed class TextLanguage : MongoStringIdentifiable
{
[Attr]
public string IsoCode { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.Meta
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class SupportTicket : MongoIdentifiable
public sealed class SupportTicket : MongoObjectIdentifiable
{
[Attr]
public string Description { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.QueryStrings
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class AccountPreferences : MongoIdentifiable
public sealed class AccountPreferences : MongoObjectIdentifiable
{
[Attr]
public bool UseDarkTheme { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.QueryStrings
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class Appointment : MongoIdentifiable
public sealed class Appointment : MongoObjectIdentifiable
{
[Attr]
public string Title { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.QueryStrings
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class Blog : MongoIdentifiable
public sealed class Blog : MongoObjectIdentifiable
{
[Attr]
public string Title { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.QueryStrings
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class BlogPost : MongoIdentifiable
public sealed class BlogPost : MongoObjectIdentifiable
{
[Attr]
public string Caption { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.QueryStrings
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class Calendar : MongoIdentifiable
public sealed class Calendar : MongoObjectIdentifiable
{
[Attr]
public string TimeZone { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.QueryStrings
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class Comment : MongoIdentifiable
public sealed class Comment : MongoObjectIdentifiable
{
[Attr]
public string Text { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.QueryStrings.Filtering
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class FilterableResource : MongoIdentifiable
public sealed class FilterableResource : MongoObjectIdentifiable
{
[Attr]
public string SomeString { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.QueryStrings
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class Label : MongoIdentifiable
public sealed class Label : MongoObjectIdentifiable
{
[Attr]
public string Name { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.QueryStrings
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class WebAccount : MongoIdentifiable
public sealed class WebAccount : MongoObjectIdentifiable
{
[Attr]
public string UserName { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public async Task Can_create_resource_with_client_generated_string_ID_having_no_
{
// Arrange
RgbColor newColor = _fakers.RgbColor.Generate();
newColor.Id = "507f191e810c19729de860ea";
newColor.Id = "free-format-client-generated-id";

var requestBody = new
{
Expand Down Expand Up @@ -72,7 +72,7 @@ public async Task Can_create_resource_with_client_generated_string_ID_having_sid
{
// Arrange
WorkItemGroup newGroup = _fakers.WorkItemGroup.Generate();
newGroup.Id = "5ffcc0d1d69a27c92b8c62dd";
newGroup.Id = "free-format-client-generated-id";

var requestBody = new
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.ReadWrite
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class RgbColor : MongoIdentifiable
public sealed class RgbColor : MongoStringIdentifiable
{
[Attr]
public string DisplayName { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.ReadWrite
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class UserAccount : MongoIdentifiable
public sealed class UserAccount : MongoObjectIdentifiable
{
[Attr]
public string FirstName { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.ReadWrite
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class WorkItem : MongoIdentifiable
public sealed class WorkItem : MongoObjectIdentifiable
{
[Attr]
public string Description { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.ReadWrite
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class WorkItemGroup : MongoIdentifiable
public sealed class WorkItemGroup : MongoStringIdentifiable
{
[Attr]
public string Name { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.ReadWrite
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class WorkTag : MongoIdentifiable
public sealed class WorkTag : MongoObjectIdentifiable
{
[Attr]
public string Text { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace JsonApiDotNetCoreMongoDbExampleTests.IntegrationTests.ResourceDefinitions
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class CallableResource : MongoIdentifiable
public sealed class CallableResource : MongoObjectIdentifiable
{
[Attr]
public string Label { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using JsonApiDotNetCore.Resources;
using JsonApiDotNetCore.MongoDb.Resources;
using MongoDB.Driver.Linq;

namespace JsonApiDotNetCoreMongoDbExampleTests.TestBuildingBlocks
Expand All @@ -10,7 +10,7 @@ internal static class MongoQueryableExtensions
{
public static async Task<TResource> FirstWithIdAsync<TResource, TId>(this IMongoQueryable<TResource> resources, TId id,
CancellationToken cancellationToken = default)
where TResource : IIdentifiable<TId>
where TResource : IMongoIdentifiable
{
TResource firstOrDefault = await resources.FirstOrDefaultAsync(resource => Equals(resource.Id, id), cancellationToken);

Expand All @@ -24,7 +24,7 @@ public static async Task<TResource> FirstWithIdAsync<TResource, TId>(this IMongo

public static Task<TResource> FirstWithIdOrDefaultAsync<TResource, TId>(this IMongoQueryable<TResource> resources, TId id,
CancellationToken cancellationToken = default)
where TResource : IIdentifiable<TId>
where TResource : IMongoIdentifiable
{
return resources.FirstOrDefaultAsync(resource => Equals(resource.Id, id), cancellationToken);
}
Expand Down