Skip to content

Feat/serializer context decoupling #558

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

Merged
merged 94 commits into from
Oct 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
1f8a3f8
feat: started work on decoupling
May 3, 2019
88235e8
feat: add total record count
May 3, 2019
1a94a49
feat: green tests, new managers
May 13, 2019
ab78ad2
feat: changed startup
May 17, 2019
5da1a86
feat: most annoying commit of my life, rewriting dozens of controllers
May 17, 2019
494f6eb
feat: rename: QueryManager -> RequestManager, deeper seperation of co…
May 23, 2019
77a2ae9
feat: removed JsonApiContext dependency from controller, fixed namesp…
May 24, 2019
94615f8
feat: decoupled controllers
May 24, 2019
4a53c00
chore: renamed resourcegraphbuilder, took out some extensions, made …
May 27, 2019
0547fe5
chore: merge + refactor to allow for old code
Jul 2, 2019
afb02f2
feat: json api context decoupling mroe and more
Jul 2, 2019
fa954be
fix: merge with master
Aug 15, 2019
2be340b
chore: readded solutions
Aug 15, 2019
6796295
feat: upgrading to 2.2, setting contextentity in middleware
Sep 2, 2019
0d21254
fix: removed outdated authorization test
Sep 3, 2019
ab02766
fix: requestmeta tests
Sep 3, 2019
7246ca9
fix: some acceptance tests
Sep 5, 2019
c177659
fix: pagination
Sep 5, 2019
857b8a9
fix: total records in meta
Sep 6, 2019
4eec35a
feat: introduced JsonApiActionFilter
Sep 6, 2019
d672e8e
fix: more tests
Sep 9, 2019
0704cc6
feat: decoupled deserializer and serializer
Sep 26, 2019
5745c44
chore: remove / cleanup old serializers
Sep 26, 2019
b679f07
chore: remove operation services
Sep 26, 2019
12d43ed
tests: unit tests client/server (de)serializers
Sep 26, 2019
03f4b7a
chore: various edits to run tests
Sep 26, 2019
39742a7
fix: rm dasherized resolver
Sep 26, 2019
3721b7d
chore: remove JsonApiContext and corresponding interface
Sep 27, 2019
4ee770e
chore: merge dev-v4
Sep 27, 2019
09c0b54
chore: reorganize namespaces
Sep 27, 2019
2258b76
chore: rm old tests
Sep 30, 2019
13891b3
chore: rm unused document builder
Sep 30, 2019
7bc3c72
chore: add comments to deserialization classes
Sep 30, 2019
81be59f
chore: add comments
Sep 30, 2019
def3ebe
chore: rm IJsonApiContext from sort attr instantiation
Oct 1, 2019
a807d1c
feat: (re)introduced omit null value behaviour (and now omit default …
Oct 1, 2019
7cbd856
chore: remove more jsonapicontext references
Oct 1, 2019
3d1c63b
chore: minor renames, add wiki for serialization
Oct 3, 2019
765c1f8
chore: improve wiki
Oct 3, 2019
ec7ab7b
chore: wiki
Oct 3, 2019
891e94b
chore: wiki
Oct 3, 2019
fa85b32
chore: add a bunch of comments, renamed a few services
Oct 3, 2019
40de0d6
chore: wired up nested sparse field selection
Oct 3, 2019
d8e8668
chore: wired up omit behaviour
Oct 3, 2019
60f033c
chore: prettied some comments
Oct 3, 2019
bf4547a
chore: remove (almost) all references to jsonapicontext in unit tests…
Oct 3, 2019
013fccb
chore: removed last bits of jsonapicontext
Oct 3, 2019
b5530a4
fix: tests serialization passing again
Oct 3, 2019
5ff3842
chore: rename included query service to include query service
Oct 3, 2019
819b65f
chore: improve comment
Oct 3, 2019
50cc904
chore: improve comment
Oct 3, 2019
be5b652
chore: delete jsonapicontext tests
Oct 3, 2019
ec9753f
chore: remove space
Oct 3, 2019
3f8399e
test: email config
maurei Oct 3, 2019
a5c3cc8
chore: rename client / server (de)serializer to request/response (de)…
maurei Oct 3, 2019
90f6b8c
chore: rename client / server (de)serializer to request/response (de)…
maurei Oct 3, 2019
45cbc13
feat: introduce IQueryParameter
maurei Oct 4, 2019
efc8614
chore: move request/response (de)serializer to client/server namespac…
maurei Oct 4, 2019
93cdb27
chore: update namespaces
maurei Oct 4, 2019
c092142
chore: rm textfile
maurei Oct 4, 2019
4525d65
chore: fixing failing unit tests
maurei Oct 4, 2019
93ab64b
chore: rename query services, adjustment namespace
maurei Oct 4, 2019
dad0901
chore: reorganised test files for serialization, added relationship p…
maurei Oct 4, 2019
bb495d7
feat: request relationship in response serializer
maurei Oct 4, 2019
fd356c5
chore: wired up response serializer in formatter layer
maurei Oct 4, 2019
eadf49e
feat: IGetRelationshipService now returns TResource instead of object…
maurei Oct 4, 2019
9ec2137
fix: support for serving document of resource type different from req…
maurei Oct 4, 2019
2f79331
chore: simplified linkbuilders
maurei Oct 5, 2019
21a285d
chore: several fixes for e2e tests
maurei Oct 7, 2019
a89f320
fix: various e2e tests, decoupled service layer from serialization fo…
maurei Oct 7, 2019
e16c272
fix: inclusion edgecase
maurei Oct 7, 2019
032362d
chore: fix error formatting tests
maurei Oct 8, 2019
d25abe7
chore: naming consistency sparsefield and include query services
maurei Oct 8, 2019
a9ff8cf
chore: various adjustments to make e2e test project build and pass again
maurei Oct 8, 2019
7e44e57
chore: fix build various e2e tests
maurei Oct 8, 2019
c6b4495
chore: fix build various e2e tests
maurei Oct 8, 2019
de8b530
fix: e2e test Can_Include_Nested_Relationships
maurei Oct 8, 2019
ce5b46a
fix: e2e test Can_Patch_Entity
maurei Oct 8, 2019
060da88
fix: e2e test Patch_Entity_With_HasMany_Does_Not_Include_Relationships
maurei Oct 8, 2019
f719c59
fix: e2e test Can_Create_Entity_With_Client_Defined_Id_If_Configured
maurei Oct 8, 2019
2c33407
chore: rename base document parser and builder
maurei Oct 8, 2019
f3d5e45
fix: e2e test Can_Create_Guid_Identifiable_Entity_With_Client_Defined…
maurei Oct 8, 2019
4f592bd
fix: unit tests various
maurei Oct 8, 2019
0abb063
feat: reorganisation inheritance serialization layer
maurei Oct 8, 2019
c8ff443
fix: unit tests after inheritance update
maurei Oct 9, 2019
6427504
fix: wire up correct resource object builder implementation in serial…
maurei Oct 9, 2019
1c5517b
fix: e2e remaining CreatingDataTests
maurei Oct 9, 2019
441f538
chore: refactor creatingdata tests
maurei Oct 9, 2019
90ab6e6
fix: e2e test paging
maurei Oct 9, 2019
e5bbda2
fix: e2e controller tests
maurei Oct 9, 2019
883bfee
chore: wiring up new resource object builders to dependency graph
maurei Oct 9, 2019
b13f55e
chore: response resource object builder unit test, restored repo and …
maurei Oct 10, 2019
c55672b
chore: finishing touches comments serialization
maurei Oct 10, 2019
bd75894
Feat/serialization wiki (#561)
wisepotato Oct 10, 2019
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 benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Benchmarks {
class Program {
static void Main(string[] args) {
var switcher = new BenchmarkSwitcher(new[] {
typeof(JsonApiDeserializer_Benchmarks),
typeof(JsonApideserializer_Benchmarks),
//typeof(JsonApiSerializer_Benchmarks),
typeof(QueryParser_Benchmarks),
typeof(LinkBuilder_GetNamespaceFromPath_Benchmarks),
Expand Down
8 changes: 4 additions & 4 deletions benchmarks/Query/QueryParser_Benchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public class QueryParser_Benchmarks {
private const string DESCENDING_SORT = "-" + ATTRIBUTE;

public QueryParser_Benchmarks() {
var requestMock = new Mock<IRequestManager>();
requestMock.Setup(m => m.GetContextEntity()).Returns(new ContextEntity {
var requestMock = new Mock<IRequestContext>();
requestMock.Setup(m => m.GetRequestResource()).Returns(new ContextEntity {
Attributes = new List<AttrAttribute> {
new AttrAttribute(ATTRIBUTE, ATTRIBUTE)
}
Expand Down Expand Up @@ -59,8 +59,8 @@ private void Run(int iterations, Action action) {
// this facade allows us to expose and micro-benchmark protected methods
private class BenchmarkFacade : QueryParser {
public BenchmarkFacade(
IRequestManager requestManager,
JsonApiOptions options) : base(requestManager, options) { }
IRequestContext currentRequest,
JsonApiOptions options) : base(currentRequest, options) { }

public void _ParseSortParameters(string value) => base.ParseSortParameters(value);
}
Expand Down
16 changes: 9 additions & 7 deletions benchmarks/Serialization/JsonApiDeserializer_Benchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using JsonApiDotNetCore.Managers.Contracts;
using JsonApiDotNetCore.Models;
using JsonApiDotNetCore.Serialization;
using JsonApiDotNetCore.Serialization.Contracts;

using JsonApiDotNetCore.Services;
using Moq;
using Newtonsoft.Json;
Expand All @@ -15,7 +17,7 @@
namespace Benchmarks.Serialization
{
[MarkdownExporter]
public class JsonApiDeserializer_Benchmarks {
public class JsonApideserializer_Benchmarks {
private const string TYPE_NAME = "simple-types";
private static readonly string Content = JsonConvert.SerializeObject(new Document {
Data = new ResourceObject {
Expand All @@ -30,15 +32,15 @@ public class JsonApiDeserializer_Benchmarks {
}
});

private readonly JsonApiDeSerializer _jsonApiDeSerializer;
private readonly JsonApideserializer _jsonApideserializer;

public JsonApiDeserializer_Benchmarks() {
public JsonApideserializer_Benchmarks() {
var resourceGraphBuilder = new ResourceGraphBuilder();
resourceGraphBuilder.AddResource<SimpleType>(TYPE_NAME);
var resourceGraph = resourceGraphBuilder.Build();
var requestManagerMock = new Mock<IRequestManager>();
var currentRequestMock = new Mock<IRequestContext>();

requestManagerMock.Setup(m => m.GetUpdatedAttributes()).Returns(new Dictionary<AttrAttribute, object>());
currentRequestMock.Setup(m => m.GetUpdatedAttributes()).Returns(new Dictionary<AttrAttribute, object>());

var jsonApiContextMock = new Mock<IJsonApiContext>();
jsonApiContextMock.SetupAllProperties();
Expand All @@ -50,11 +52,11 @@ public JsonApiDeserializer_Benchmarks() {
jsonApiContextMock.Setup(m => m.Options).Returns(jsonApiOptions);


_jsonApiDeSerializer = new JsonApiDeSerializer(jsonApiContextMock.Object, requestManagerMock.Object);
_jsonApideserializer = new JsonApideserializer(jsonApiContextMock.Object, currentRequestMock.Object);
}

[Benchmark]
public object DeserializeSimpleObject() => _jsonApiDeSerializer.Deserialize<SimpleType>(Content);
public object DeserializeSimpleObject() => _jsonApideserializer.Deserialize<SimpleType>(Content);

private class SimpleType : Identifiable {
[Attr("name")]
Expand Down
4 changes: 3 additions & 1 deletion benchmarks/Serialization/JsonApiSerializer_Benchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//using JsonApiDotNetCore.Internal.Generics;
//using JsonApiDotNetCore.Models;
//using JsonApiDotNetCore.Serialization;
using JsonApiDotNetCore.Serialization.Contracts;

//using JsonApiDotNetCore.Services;
//using Moq;
//using Newtonsoft.Json.Serialization;
Expand Down Expand Up @@ -34,7 +36,7 @@

// var genericProcessorFactoryMock = new Mock<IGenericProcessorFactory>();

// var documentBuilder = new DocumentBuilder(jsonApiContextMock.Object);
// var documentBuilder = new BaseDocumentBuilder(jsonApiContextMock.Object);
// _jsonApiSerializer = new JsonApiSerializer(jsonApiContextMock.Object, documentBuilder);
// }

Expand Down
1 change: 0 additions & 1 deletion src/Examples/GettingStarted/Models/Article.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ public class Article : Identifiable
{
[Attr]
public string Title { get; set; }

[HasOne]
public Person Author { get; set; }
public int AuthorId { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Controllers;
using JsonApiDotNetCore.Internal.Contracts;
using JsonApiDotNetCore.Services;
using JsonApiDotNetCoreExample.Models;
using Microsoft.Extensions.Logging;

namespace JsonApiDotNetCoreExample.Controllers
{
public class PassportsController : JsonApiController<Passport>
{
public PassportsController(
IJsonApiContext jsonApiContext,
IResourceService<Passport> resourceService)
: base(jsonApiContext, resourceService)
{ }
public PassportsController(IJsonApiOptions jsonApiOptions, IResourceGraph resourceGraph, IResourceService<Passport, int> resourceService, ILoggerFactory loggerFactory = null) : base(jsonApiOptions, resourceGraph, resourceService, loggerFactory)
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,19 @@ namespace JsonApiDotNetCoreExample.Controllers
public class TodoItemsCustomController : CustomJsonApiController<TodoItem>
{
public TodoItemsCustomController(
IJsonApiContext jsonApiContext,
IResourceService<TodoItem> resourceService,
ILoggerFactory loggerFactory)
: base(jsonApiContext, resourceService, loggerFactory)
: base(resourceService, loggerFactory)
{ }
}

public class CustomJsonApiController<T>
: CustomJsonApiController<T, int> where T : class, IIdentifiable<int>
{
public CustomJsonApiController(
IJsonApiContext jsonApiContext,
IResourceService<T, int> resourceService,
ILoggerFactory loggerFactory)
: base(jsonApiContext, resourceService, loggerFactory)
: base(resourceService, loggerFactory)
{ }
}

Expand All @@ -36,28 +34,23 @@ public class CustomJsonApiController<T, TId>
{
private readonly ILogger _logger;
private readonly IResourceService<T, TId> _resourceService;
private readonly IJsonApiContext _jsonApiContext;

protected IActionResult Forbidden()
{
return new StatusCodeResult(403);
}

public CustomJsonApiController(
IJsonApiContext jsonApiContext,
IResourceService<T, TId> resourceService,
ILoggerFactory loggerFactory)
{
_jsonApiContext = jsonApiContext.ApplyContext<T>(this);
_resourceService = resourceService;
_logger = loggerFactory.CreateLogger<JsonApiDotNetCore.Controllers.JsonApiController<T, TId>>();
}

public CustomJsonApiController(
IJsonApiContext jsonApiContext,
IResourceService<T, TId> resourceService)
{
_jsonApiContext = jsonApiContext.ApplyContext<T>(this);
_resourceService = resourceService;
}

Expand Down Expand Up @@ -102,8 +95,8 @@ public virtual async Task<IActionResult> PostAsync([FromBody] T entity)
if (entity == null)
return UnprocessableEntity();

if (!_jsonApiContext.Options.AllowClientGeneratedIds && !string.IsNullOrEmpty(entity.StringId))
return Forbidden();
//if (!_jsonApiContext.Options.AllowClientGeneratedIds && !string.IsNullOrEmpty(entity.StringId))
// return Forbidden();

entity = await _resourceService.CreateAsync(entity);

Expand Down
15 changes: 3 additions & 12 deletions src/Examples/JsonApiDotNetCoreExample/Models/Person.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using JsonApiDotNetCore.Models;
using JsonApiDotNetCore.Services;
using JsonApiDotNetCore.Models.Links;

namespace JsonApiDotNetCoreExample.Models
{
Expand All @@ -11,7 +10,7 @@ public class PersonRole : Identifiable
public Person Person { get; set; }
}

public class Person : Identifiable, IHasMeta, IIsLockable
public class Person : Identifiable, IIsLockable
{
public bool IsLocked { get; set; }

Expand Down Expand Up @@ -45,21 +44,13 @@ public class Person : Identifiable, IHasMeta, IIsLockable
public virtual TodoItem StakeHolderTodo { get; set; }
public virtual int? StakeHolderTodoId { get; set; }

[HasOne("unincludeable-item", documentLinks: Link.All, canInclude: false)]
[HasOne("unincludeable-item", links: Link.All, canInclude: false)]
public virtual TodoItem UnIncludeableItem { get; set; }

public int? PassportId { get; set; }

[HasOne("passport")]
public virtual Passport Passport { get; set; }

public Dictionary<string, object> GetMeta(IJsonApiContext context)
{
return new Dictionary<string, object> {
{ "copyright", "Copyright 2015 Example Corp." },
{ "authors", new string[] { "Jared Nance" } }
};
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ public class TodoItemCollection : Identifiable<Guid>
{
[Attr("name")]
public string Name { get; set; }
public int OwnerId { get; set; }

[HasMany("todo-items")]
public virtual List<TodoItem> TodoItems { get; set; }

[HasOne("owner")]
public virtual Person Owner { get; set; }
public int? OwnerId { get; set; }
}
}
5 changes: 3 additions & 2 deletions src/Examples/JsonApiDotNetCoreExample/Models/User.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System;
using JsonApiDotNetCore.Models;

namespace JsonApiDotNetCoreExample.Models
{
public class User : Identifiable
{
[Attr("username")] public string Username { get; set; }
[Attr("password")] public string Password { get; set; }
[Attr] public string Username { get; set; }
[Attr] public string Password { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using JsonApiDotNetCore.Internal;
using JsonApiDotNetCore.Internal.Contracts;
using JsonApiDotNetCore.Models;
using JsonApiDotNetCore.Services;
using JsonApiDotNetCoreExample.Models;

namespace JsonApiDotNetCoreExample.Resources
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
using JsonApiDotNetCore.Hooks;
using JsonApiDotNetCoreExample.Models;
using JsonApiDotNetCore.Internal.Contracts;
using JsonApiDotNetCore.Models;

namespace JsonApiDotNetCoreExample.Resources
{
public class PersonResource : LockableResource<Person>
public class PersonResource : LockableResource<Person>, IHasMeta
{
public PersonResource(IResourceGraph graph) : base(graph) { }

public override IEnumerable<Person> BeforeUpdate(IDiffableEntityHashSet<Person> entities, ResourcePipeline pipeline)
{
return base.BeforeUpdate(entities, pipeline);
}

public override IEnumerable<string> BeforeUpdateRelationship(HashSet<string> ids, IRelationshipsDictionary<Person> entitiesByRelationship, ResourcePipeline pipeline)
{
BeforeImplicitUpdateRelationship(entitiesByRelationship, pipeline);
Expand All @@ -20,5 +26,13 @@ public override void BeforeImplicitUpdateRelationship(IRelationshipsDictionary<P
{
entitiesByRelationship.GetByRelationship<Passport>().ToList().ForEach(kvp => DisallowLocked(kvp.Value));
}

public Dictionary<string, object> GetMeta()
{
return new Dictionary<string, object> {
{ "copyright", "Copyright 2015 Example Corp." },
{ "authors", new string[] { "Jared Nance", "Maurits Moeys" } }
};
}
}
}
11 changes: 5 additions & 6 deletions src/Examples/JsonApiDotNetCoreExample/Resources/UserResource.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
using System.Collections.Generic;
using System.Linq;
using JsonApiDotNetCore.Models;
using JsonApiDotNetCoreExample.Models;
using JsonApiDotNetCore.Internal.Query;
using JsonApiDotNetCore.Internal.Contracts;

using JsonApiDotNetCore.Services;

namespace JsonApiDotNetCoreExample.Resources
{
public class UserResource : ResourceDefinition<User>
{
public UserResource(IResourceGraph graph) : base(graph) { }

protected override List<AttrAttribute> OutputAttrs()
=> Remove(user => user.Password);
public UserResource(IResourceGraph graph, IFieldsExplorer fieldExplorer) : base(fieldExplorer, graph)
{
HideFields(u => u.Password);
}

public override QueryFilters GetQueryFilters()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
using JsonApiDotNetCore.Internal;
using JsonApiDotNetCore.Internal.Contracts;
using JsonApiDotNetCore.Managers.Contracts;
using JsonApiDotNetCore.Models;
using JsonApiDotNetCore.Query;
using JsonApiDotNetCore.Serialization;
using JsonApiDotNetCore.Services;
using JsonApiDotNetCoreExample.Models;
using Microsoft.Extensions.Logging;
Expand All @@ -13,16 +16,9 @@ namespace JsonApiDotNetCoreExample.Services
{
public class CustomArticleService : EntityResourceService<Article>
{
public CustomArticleService(
IEntityRepository<Article> repository,
IJsonApiOptions jsonApiOptions,
IRequestManager queryManager,
IPageManager pageManager,
IResourceGraph resourceGraph,
IResourceHookExecutor resourceHookExecutor = null,
ILoggerFactory loggerFactory = null
) : base(repository: repository, jsonApiOptions, queryManager, pageManager, resourceGraph:resourceGraph, loggerFactory, resourceHookExecutor)
{ }
public CustomArticleService(IEntityRepository<Article, int> repository, IJsonApiOptions options, ITargetedFields updatedFields, ICurrentRequest currentRequest, IIncludeService includeService, ISparseFieldsService sparseFieldsService, IPageQueryService pageManager, IResourceGraph resourceGraph, IResourceHookExecutor hookExecutor = null, IResourceMapper mapper = null, ILoggerFactory loggerFactory = null) : base(repository, options, updatedFields, currentRequest, includeService, sparseFieldsService, pageManager, resourceGraph, hookExecutor, mapper, loggerFactory)
{
}

public override async Task<Article> GetAsync(int id)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Examples/JsonApiDotNetCoreExample/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public virtual IServiceProvider ConfigureServices(IServiceCollection services)
options.DefaultPageSize = 5;
options.IncludeTotalRecordCount = true;
options.EnableResourceHooks = true;
options.LoadDatabaseValues = true;
options.LoaDatabaseValues = true;
},
discovery => discovery.AddCurrentAssembly());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public Task<object> GetRelationshipAsync(int id, string relationshipName)
throw new NotImplementedException();
}

public Task<object> GetRelationshipsAsync(int id, string relationshipName)
public Task<TodoItem> GetRelationshipsAsync(int id, string relationshipName)
{
throw new NotImplementedException();
}
Expand All @@ -84,7 +84,7 @@ public Task<TodoItem> UpdateAsync(int id, TodoItem entity)
throw new NotImplementedException();
}

public Task UpdateRelationshipsAsync(int id, string relationshipName, List<ResourceObject> relationships)
public Task UpdateRelationshipsAsync(int id, string relationshipName, object relationships)
{
throw new NotImplementedException();
}
Expand Down
Loading