2

In my limited understanding of microservices they seem to focus on quite limited pools of information, leaving it up to the application to bring all the data together in ways which were perhaps not anticipated.

I am working through a simple project in an attempt to get up-to-speed with a number of new concepts for me. The application is for a library consisting of books. A book has an Id, a title and a number of 'can-haves'. For example, 0 or more authors, 0 or more editors, 0 or more translators etc.

The books are in one table, the people in another table and the relationships in a third table.

@IdClass(BookAuthorId.class)
public class BookAuthor {
    @Id
    private char type;  //A=Author, E=Editor, T=Trl8r

    @Id
    @JsonProperty("BOOK_ID")
    private Long bookId;

    @Id
    @JsonProperty("AUTH_ID")
    private Long authorId;
}

I could put these relationships directly into the book model but I'm thinking of a different approach where the authors are picked up in a separate call.

http://host/api/book/{bookid}

http://host/api/book/{bookid}/author
http://host/api/book/{bookid}/editor
http://host/api/book/{bookid}/translator

It seems to me that the data returned is kept to a minimum and the queries are kept ultra simple and data contract is probably easier to maintain.

On the downside, the number of calls increases but this might be mitigated by the use of a Backend-for-Frontend layer which would marshal all the information on the server side and not in the client.

For my simple project I'm sure either way will work fine but I'm wondering how these 2 approaches would pan out in the real world.

  • Is one more scalable?
  • Is one more difficult to maintain?
  • Should one be avoided at all costs?
4

There is a misunderstanding here. Microservices are not designed to work “on a limited pool of data”.

Microservices are designed to be losely coupled, independently deployable and scalable. An effective pattern to support these objectives is to let each microservice have its own database. Why ?

  • a shared database might limit scalability;
  • a shared database between different microservice might create a risk of hidden dependency via the db schema

Artificially limiting the amount of data by avoiding joins (that db can do much better than your handcrafted algorithms) does not enter into this consideration.

Of course, my answer would be different if you’d talk about tables that should belong to different microservices. But in this case, my argument would be about decoupling the data, and not about avoiding joins. By the way, you would not do the join anyhow, because the tables would be in different databases ;-)

This brings us to the question of granularity of microservices: If its’s about books and infos describing the book, there is no need to artificially split these down into its bare elements. If it’s about books on one side and really about persons on the other (e.g. because you need to track authors, manage their copyright contracts, etc... ) then we could start to think about different microservices. In this regard, you may be interested to follow Chris Richardson’s guidance about microservice decomposition: by business capability, by subdomain, by self-standing service, or by team responsibility.

3

A lot of it depends on the access patterns of the data, based on which your database is designed and this further influences your design of the microservices.

You can think of splitting your entities along verticals (as in Books, Authors and Relationships in separate tables), which in a way automatically leads to 3 different microservices. Of course, in a more complex case, joins and aggregations would cost more, but that's one decision making criterion, do you really access data in a way that needs a lot of joins? If so, it is better to split your database not based on entities, but based on business functionality. You are likely to have your entities, but will serve requests from a preprocessed aggregated view.

Is one more scalable?
Generally, as long as your underlying entities have been separated to create a level of isolation, which allows for minimum cascading effects on changes, solving for scale is much easier. That is particularly true when you working in dynamic environments where requirement changes happen frequently.

Is one more difficult to maintain? You have to solve for one problem or the other. If entities are normalised and you require a lot of operations on multiple tables, you are bloating up your application, on the flip side, your database would bloat up if you intend to reduce application complexity.

Should one be avoided at all costs? Nope. It's a matter of what works for you. Depending on the type and complexity of the application, none of the existing designs or solutions might work for you (chances are fewer, but hey..). This situation is what will lead to more patterns and architectural styles being formed, and newer solutions in hardware and software will come to light. Generally, a hybrid approach adopted might help to get to a solution too, and in most cases a seemingly non optimal but much simpler design might be to your liking.

2

I find this depends on how generic you need the microservice to be.

Say you have a microservice which sends emails. You might have a bunch of tables for addresses, body, attachments etc, but the user of the service wont know or care about that. They will just send a single blob of data and expect you to send a bunch of emails.

However, you might have another microservice which manages your customer orders. Now this will be used by a whole bunch of other systems, the shop, the stock room, marketing etc and each will use the data in a different way, so providing it in simple lists of each data type is easier all around.

eg marketing will want a drop down list of customers, the shop will want a list of products with prices. you cant predict the scope of the data so you give it out in a generic form and let the calling app stitch it together

0

Here's two ideas and techniques that deal with the question "How much data should be returned in a REST API call?" knowing that REST APIs should be designed for an API user (to make sense from the user's perspective) but not over-specialize on one client or use case

json:api introduces a powerful concept of related resources and their inclusion. In this model, the server can include additional data if it anticipates the client needing them. You could also pass in query hints or headers to direct this behavior. You can do this without json:api as well, but I find the concepts well formalized explained there.

GraphQL then moves to a concept where the caller gets to specify which fields and which related items are to be returned.

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.