2

We use C# MVC and Angularjs as the primary tools to develop our web applications. We've recently been discussing best practices, with an eye towards revising our development approaches into something a bit more structured.

One of the topics is how we handle APIs.

More specifically, we're looking to utilize web APIs as a means of communicating from the client-side AngularJS controllers and the server-side C# controllers. Basic model data would be passed from the C# controller through the view into the DOM, but dynamic elements would be loaded via Ajax calls to the web APIs.

This led to the question: how do we organize our APIs?

Our data models for these APIs seem to generally fall into one of two categories: complex models representing data object hierarchies, and simple models for dynamically populating the view (such as loading ng-options for select tags).

We're not planning on going fully RESTful, unless the specific project identifies that APIs will be exposed to third party entities, since properly configuring HATEOAS seems overkill for APIs that are intended as purely internal.

An alternative to having both complex data object APIs and very simple APIs would be to only use complex data objects, and to include in those objects every dependent list that could be needed within the view. My main concern with that approach is that some of these complex models could get very large, which could significantly impact performance. Of course, a ton of small API calls could also impact performance.

By way of example, one of the objects in a current project is a document type that can have one or more tasks associated with it (and each task is associated with a single parent document).

Within the module associated with that document, loading all of the tasks associated with it as part of the main API call makes sense. However, that document object is referenced in other places within the application where we want the users to choose one instance of that document type, at which point a second drop-down becomes populated with all the tasks associated with that document.

Having a page load hundreds or thousands of these documents, including up to half-a-dozen or so tasks for each of those documents, seems likely to be a bigger hit to performance than a single call to retrieve the ID and description of each document, and then having a second API trigger on selection, which would load the task drop-down with just the tasks associated with that document.

Is this strategy of mixing complex model APIs and simple APIs a good idea? What are the main pitfalls to watch out for? Is there a better architecture to employ?

1

One approach I like, to use your own term, is having "complex models" but asking the server how deeply you want the model to be filled.

In your example, you might have an API call:

GET /project?id=1337

That will return some basic representation of your model with attributes common across all use cases. Now you might be able to call the API with additional parameters:

GET /project?id=1337&include=tasks

You can use these parameters to indicate that the server should include additional data in your model. You could support multiple mutually exclusive includes, conventions based on "paths" in your model, or whatever you want.

I like this because you only need a single API but it can support multiple use cases. And it works well with caching and other optimization strategies.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.