Skip to content

Commit 770aea8

Browse files
committed
use local ids instead of JsonPointers
1 parent 31a1e8b commit 770aea8

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/JsonApiDotNetCore/Services/Operations/OperationsProcessor.cs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using System.Threading.Tasks;
45
using JsonApiDotNetCore.Data;
56
using JsonApiDotNetCore.Internal;
7+
using JsonApiDotNetCore.Models;
68
using JsonApiDotNetCore.Models.Operations;
79
using JsonApiDotNetCore.Models.Pointers;
810
using Microsoft.EntityFrameworkCore;
@@ -61,7 +63,7 @@ private async Task ProcessOperation(Operation op, List<Operation> outputOps)
6163
{
6264
var operationsPointer = new OperationsPointer();
6365

64-
// ReplaceDataPointers(op.DataObject, outputOps);
66+
ReplaceDataPointers(op.DataObject, outputOps);
6567
// ReplaceRefPointers(op.Ref, outputOps);
6668

6769
var processor = GetOperationsProcessor(op);
@@ -71,6 +73,43 @@ private async Task ProcessOperation(Operation op, List<Operation> outputOps)
7173
outputOps.Add(resultOp);
7274
}
7375

76+
private void ReplaceDataPointers(DocumentData data, List<Operation> outputOps)
77+
{
78+
if (data == null) return;
79+
80+
bool HasLocalId(ResourceIdentifierObject rio) => string.IsNullOrEmpty(rio.LocalId) == false;
81+
string GetIdFromLocalId(string localId) {
82+
var referencedOp = outputOps.FirstOrDefault(o => o.DataObject.LocalId == localId);
83+
if(referencedOp == null) throw new JsonApiException(400, $"Could not locate lid '{localId}' in document.");
84+
return referencedOp.DataObject.Id;
85+
};
86+
87+
// are there any circumstances where the primary data would contain an lid?
88+
// if(HasLocalId(data))
89+
// {
90+
// data.Id = GetIdFromLocalId(data.LocalId);
91+
// }
92+
93+
if (data.Relationships != null)
94+
{
95+
foreach (var relationshipDictionary in data.Relationships)
96+
{
97+
if (relationshipDictionary.Value.IsHasMany)
98+
{
99+
foreach (var relationship in relationshipDictionary.Value.ManyData)
100+
if(HasLocalId(relationship))
101+
relationship.Id = GetIdFromLocalId(relationship.LocalId);
102+
}
103+
else
104+
{
105+
var relationship = relationshipDictionary.Value.SingleData;
106+
if(HasLocalId(relationship))
107+
relationship.Id = GetIdFromLocalId(relationship.LocalId);
108+
}
109+
}
110+
}
111+
}
112+
74113
private IOpProcessor GetOperationsProcessor(Operation op)
75114
{
76115
switch (op.Op)

test/UnitTests/Services/Operations/OperationsProcessorTests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ public OperationsProcessorTests()
2424
_resolverMock = new Mock<IOperationProcessorResolver>();
2525
_dbContextMock = new Mock<DbContext>();
2626
_dbContextResolverMock = new Mock<IDbContextResolver>();
27-
_dbContextResolverMock.Setup(m => m.GetContext()).Returns(_dbContextMock.Object);
2827
}
2928

3029
[Fact]
@@ -36,6 +35,7 @@ public async Task ProcessAsync_Performs_Pointer_ReplacementAsync()
3635
""op"": ""add"",
3736
""data"": {
3837
""type"": ""authors"",
38+
""lid"": ""a"",
3939
""attributes"": {
4040
""name"": ""dgeb""
4141
}
@@ -51,7 +51,7 @@ public async Task ProcessAsync_Performs_Pointer_ReplacementAsync()
5151
""author"": {
5252
""data"": {
5353
""type"": ""authors"",
54-
""id"": { ""pointer"": ""/operations/0/data/id"" }
54+
""lid"": ""a""
5555
}
5656
}
5757
}
@@ -66,6 +66,7 @@ public async Task ProcessAsync_Performs_Pointer_ReplacementAsync()
6666
""data"": {
6767
""type"": ""authors"",
6868
""id"": ""9"",
69+
""lid"": ""a"",
6970
""attributes"": {
7071
""name"": ""dgeb""
7172
}
@@ -91,6 +92,7 @@ public async Task ProcessAsync_Performs_Pointer_ReplacementAsync()
9192
_resolverMock.Setup(m => m.LocateCreateService((It.IsAny<Operation>())))
9293
.Returns(opProcessorMock.Object);
9394

95+
_dbContextResolverMock.Setup(m => m.GetContext()).Returns(_dbContextMock.Object);
9496
var operationsProcessor = new OperationsProcessor(_resolverMock.Object, _dbContextResolverMock.Object);
9597

9698
// act

0 commit comments

Comments
 (0)