REST API - Circular References in Normalised Data
I am developing a REST API for a database which holds information about virtual machines and servers, and certain information about them; Software installed, Disks, storage and available storage etc.
I want to be able to use this REST API to both update the database from the machines directly via an application, and also to have a web front end where users can query to find out the current status of the various machines.
I am using Entity Framework and ASP.NET MVC to scaffold the API, however I have encountered a problem which I do not have the requisite experience to solve. My work with databases in the past has been more direct and specific, I have never created an API and thus haven't needed to serialise data from a database before.
The problem I have found is that when serialising the data, in one to many and many to many relationships, for example, one object may contain a list of related objects, and each one of those may contain a reference to the parent, which then contains that same list again. So, when serialising, you end up with a potentially endless, recursive load of these objects into your serialised response. As an example:
class Machine
int ID;
string Name;
List<Software> Software;
class SoftwareInstallation
int MachineID;
int SoftwareID;
class Software
int ID;
string Name;
List<Machines> Machines;
Here is a Many to Many relationship. If I load a Machine, it will have a list of Software, each of which has a list of Machines. I could end up loading the entire database when I just want one object.
I am wondering what is the usual way to resolve this problem in API design. I don't want to send too little data for an API call, otherwise the client will have too much work to do, but I also want to avoid sending too much or worse ending up with an infinitely sized response. I am aware of concepts like Lazy and Eager loading etc. and how to invoke them with Entity Framework, however I'm unsure when to use which in order to minimise the number of API calls required whilst mitigating the risks of loading too much.
c# asp.net asp.net-mvc rest entity-framework-6
add a comment |
I am developing a REST API for a database which holds information about virtual machines and servers, and certain information about them; Software installed, Disks, storage and available storage etc.
I want to be able to use this REST API to both update the database from the machines directly via an application, and also to have a web front end where users can query to find out the current status of the various machines.
I am using Entity Framework and ASP.NET MVC to scaffold the API, however I have encountered a problem which I do not have the requisite experience to solve. My work with databases in the past has been more direct and specific, I have never created an API and thus haven't needed to serialise data from a database before.
The problem I have found is that when serialising the data, in one to many and many to many relationships, for example, one object may contain a list of related objects, and each one of those may contain a reference to the parent, which then contains that same list again. So, when serialising, you end up with a potentially endless, recursive load of these objects into your serialised response. As an example:
class Machine
int ID;
string Name;
List<Software> Software;
class SoftwareInstallation
int MachineID;
int SoftwareID;
class Software
int ID;
string Name;
List<Machines> Machines;
Here is a Many to Many relationship. If I load a Machine, it will have a list of Software, each of which has a list of Machines. I could end up loading the entire database when I just want one object.
I am wondering what is the usual way to resolve this problem in API design. I don't want to send too little data for an API call, otherwise the client will have too much work to do, but I also want to avoid sending too much or worse ending up with an infinitely sized response. I am aware of concepts like Lazy and Eager loading etc. and how to invoke them with Entity Framework, however I'm unsure when to use which in order to minimise the number of API calls required whilst mitigating the risks of loading too much.
c# asp.net asp.net-mvc rest entity-framework-6
1
Well - depending on what your API is actually going to do there is a lot or ways to solve this and many will be opinion based. One approach could be to expose an endpoint that returns a collection of Software Installations and that neither Machine nor Software related endpoins knows about the connections thus avoiding your recursive issues.
– Allan S. Hansen
Nov 13 '18 at 10:59
1
I work under the rule, don't expose your domain model through your api.
– Fran
Nov 13 '18 at 21:54
add a comment |
I am developing a REST API for a database which holds information about virtual machines and servers, and certain information about them; Software installed, Disks, storage and available storage etc.
I want to be able to use this REST API to both update the database from the machines directly via an application, and also to have a web front end where users can query to find out the current status of the various machines.
I am using Entity Framework and ASP.NET MVC to scaffold the API, however I have encountered a problem which I do not have the requisite experience to solve. My work with databases in the past has been more direct and specific, I have never created an API and thus haven't needed to serialise data from a database before.
The problem I have found is that when serialising the data, in one to many and many to many relationships, for example, one object may contain a list of related objects, and each one of those may contain a reference to the parent, which then contains that same list again. So, when serialising, you end up with a potentially endless, recursive load of these objects into your serialised response. As an example:
class Machine
int ID;
string Name;
List<Software> Software;
class SoftwareInstallation
int MachineID;
int SoftwareID;
class Software
int ID;
string Name;
List<Machines> Machines;
Here is a Many to Many relationship. If I load a Machine, it will have a list of Software, each of which has a list of Machines. I could end up loading the entire database when I just want one object.
I am wondering what is the usual way to resolve this problem in API design. I don't want to send too little data for an API call, otherwise the client will have too much work to do, but I also want to avoid sending too much or worse ending up with an infinitely sized response. I am aware of concepts like Lazy and Eager loading etc. and how to invoke them with Entity Framework, however I'm unsure when to use which in order to minimise the number of API calls required whilst mitigating the risks of loading too much.
c# asp.net asp.net-mvc rest entity-framework-6
I am developing a REST API for a database which holds information about virtual machines and servers, and certain information about them; Software installed, Disks, storage and available storage etc.
I want to be able to use this REST API to both update the database from the machines directly via an application, and also to have a web front end where users can query to find out the current status of the various machines.
I am using Entity Framework and ASP.NET MVC to scaffold the API, however I have encountered a problem which I do not have the requisite experience to solve. My work with databases in the past has been more direct and specific, I have never created an API and thus haven't needed to serialise data from a database before.
The problem I have found is that when serialising the data, in one to many and many to many relationships, for example, one object may contain a list of related objects, and each one of those may contain a reference to the parent, which then contains that same list again. So, when serialising, you end up with a potentially endless, recursive load of these objects into your serialised response. As an example:
class Machine
int ID;
string Name;
List<Software> Software;
class SoftwareInstallation
int MachineID;
int SoftwareID;
class Software
int ID;
string Name;
List<Machines> Machines;
Here is a Many to Many relationship. If I load a Machine, it will have a list of Software, each of which has a list of Machines. I could end up loading the entire database when I just want one object.
I am wondering what is the usual way to resolve this problem in API design. I don't want to send too little data for an API call, otherwise the client will have too much work to do, but I also want to avoid sending too much or worse ending up with an infinitely sized response. I am aware of concepts like Lazy and Eager loading etc. and how to invoke them with Entity Framework, however I'm unsure when to use which in order to minimise the number of API calls required whilst mitigating the risks of loading too much.
c# asp.net asp.net-mvc rest entity-framework-6
c# asp.net asp.net-mvc rest entity-framework-6
asked Nov 13 '18 at 10:37
LukeLuke
1,07352549
1,07352549
1
Well - depending on what your API is actually going to do there is a lot or ways to solve this and many will be opinion based. One approach could be to expose an endpoint that returns a collection of Software Installations and that neither Machine nor Software related endpoins knows about the connections thus avoiding your recursive issues.
– Allan S. Hansen
Nov 13 '18 at 10:59
1
I work under the rule, don't expose your domain model through your api.
– Fran
Nov 13 '18 at 21:54
add a comment |
1
Well - depending on what your API is actually going to do there is a lot or ways to solve this and many will be opinion based. One approach could be to expose an endpoint that returns a collection of Software Installations and that neither Machine nor Software related endpoins knows about the connections thus avoiding your recursive issues.
– Allan S. Hansen
Nov 13 '18 at 10:59
1
I work under the rule, don't expose your domain model through your api.
– Fran
Nov 13 '18 at 21:54
1
1
Well - depending on what your API is actually going to do there is a lot or ways to solve this and many will be opinion based. One approach could be to expose an endpoint that returns a collection of Software Installations and that neither Machine nor Software related endpoins knows about the connections thus avoiding your recursive issues.
– Allan S. Hansen
Nov 13 '18 at 10:59
Well - depending on what your API is actually going to do there is a lot or ways to solve this and many will be opinion based. One approach could be to expose an endpoint that returns a collection of Software Installations and that neither Machine nor Software related endpoins knows about the connections thus avoiding your recursive issues.
– Allan S. Hansen
Nov 13 '18 at 10:59
1
1
I work under the rule, don't expose your domain model through your api.
– Fran
Nov 13 '18 at 21:54
I work under the rule, don't expose your domain model through your api.
– Fran
Nov 13 '18 at 21:54
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53279138%2frest-api-circular-references-in-normalised-data%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53279138%2frest-api-circular-references-in-normalised-data%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Well - depending on what your API is actually going to do there is a lot or ways to solve this and many will be opinion based. One approach could be to expose an endpoint that returns a collection of Software Installations and that neither Machine nor Software related endpoins knows about the connections thus avoiding your recursive issues.
– Allan S. Hansen
Nov 13 '18 at 10:59
1
I work under the rule, don't expose your domain model through your api.
– Fran
Nov 13 '18 at 21:54