BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Presentations DDD & REST - Domain Driven APIs for the Web

DDD & REST - Domain Driven APIs for the Web

Bookmarks
01:15:02

Summary

Oliver Gierke explores some commonalities of Domain Driven Design and REST, and how to create REST APIs that are driven by the domain.

Bio

Oliver Gierke is the lead of the Spring Data project at Pivotal, formerly known as SpringSource, and member of the JPA 2.1 expert group. He has been into developing enterprise applications and open source projects for over 8 years now. His working focus is centered around software architecture, Spring, REST and persistence technologies.

About the conference

SpringOne Platform brings together the people, process and tools for delivering and operating software services. Learn and share with the startups and enterprises leveraging modern Java with Spring connecting all the pieces of the modern software puzzle from developer, operator, architect, data scientist to executive.

Recorded at:

Nov 08, 2016

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • SDR encourages bad api design

    by javadev javadev,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I agree with the problems that Oliver describes at the beginning of the talk (first 1/2 hour). But the solutions prescribed (last 45 minutes) make no sense.

    The sales-pitch for the use of spring data REST (SDR) in particular was unforgivable. It is akin to prescribing homeopathy (a few grains of sugar in 16 oz water) for influenza.

    The main problem with SDR is that it automatically exposes all the entities in the applications database.

    Due to this, the client will now have the knowledge of the data structure of the persistence layer. (and the entities/tables). IMHO, this causes the Client to be tightly coupled with the backend and the business logic for all business functions will migrate to the client/UI layer.

    And what is more, this leads to design where any application built using SDR to be fine grained where the business logic lives outside the transaction boundary and in some cases even results in a *massive N+1* problem all the way from the client's browser, over the internet all the way to the backend api and db.

    They then created projections as a workaround to this self created problem as a stand in for the DTOs, but what is the point - if one cannot even share the DTOs as a contract with the interfacing clients.

    In summary, SDR is bad news. And while it showed us some interesting patterns & ideas, the right place for SDR is six feet under.

  • Re: SDR encourages bad api design

    by Oliver Drotbohm,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Thanks for bringing that discussion up and giving me the opportunity to comment on this. The talk here is actually not about Spring Data REST but some of the ideas I present are actually derived from the work on the project of course. I also think Spring Data REST is a decent foundation to build a REST API, but I guess I say so meaning something completely different that you might assume. I'll get to that in a bit but first things first.

    Interestingly, when questions like the ones you raised, I would have pointed them to see a recording of the talk above as I actually discuss those topics in the talk. Maybe you just stopped watching before I got to these points. But let me reiterate on some of that stuff here:

    The main problem with SDR is that it automatically exposes all the entities in the applications database.


    That's not what we do and that's discussed at length in the talk. Spring Data REST implements REST API patterns on top of aggregates in the domain model. That's a crucial step over looking at entities only as it allows the framework to shape the representations of the resources exposed along the aggregate boundaries which is usually a nice fit in terms of consistency constraints, esp. when it comes to non-idempotent requests, the update for aggregates. So what you're claiming is incorrect and what's actually happening is explicitly discussed in the talk. That leaves me puzzled.

    Beyond that, you can of course disable HTTP resource exposure for repositories, control which HTTP methods are supported for the individual resources we expose etc.

    Due to this, the client will now have the knowledge of the data structure of the persistence layer. (and the entities/tables). IMHO, this causes the Client to be tightly coupled with the backend and the business logic for all business functions will migrate to the client/UI layer.


    Two things here: first, I have yet to see an REST client that can completely avoid knowing the about the semantics of the fields contained in the representation. If you're dealing with an API that exposes customer data, you will have to deal with conceptual things like a firstname and a lastname. And yes, that'll usually mean that there will be a column named like that in the database, a property named like that in the domain model and a field in the representation. That's not coupling, that's domain concepts expressed in different technical areas of the application. Also, what I was just describing is the default.

    Real coupling usually comes from clients adding additional semantics to certain fields of the representation and that's something hypermedia elements can actually help servers mitigating the problem. But in the end it's the clients task to make sure it doesn't couple too much to the structure it reads (e.g. by rather using JSON Path based mapping instead of type based mapping). Also, that is discussed in the presentation as well as a dedicated blog post I wrote.

    The second point here is that we use Jackson as JSON mapping library and you have all the means available to tweak the representation, register custom serializers etc., just as you can do on the database layer using the mapping annotations in place for that purpose. Let me raise the counter question: what do you propose instead? There is a mapping step available that you can use to make sure that changes to the domain model don't necessarily leak into changes in the API. The 1:1 mapping you see is just the default.

    And then finally N+1 selects problem and projections. The funny thing about that is that this is of course not a problem that Spring Data REST creates but the fact that representations have boundaries and the boundaries might be appropriate and sufficient for one client, whereas they might not be for another. And that's totally independent whether you decide to run with the defaults that we chose or implement all of this yourself.

    Using server side DTOs on the client is probably just as a big anti-pattern as you'd like to describe Spring Data REST, because it's exactly creating the coupling you are complaining about in the beginning. So again SDR is not the root cause. If the way a representation looks doesn't fit your needs, disable SDR for it and just write a Spring MVC controller manually. What you get are defaults, not something that's set in stone and has to be used.

    Let me take a step back and quickly elaborate on the motivation behind SDR. I guess that could clear up a lot of misconceptions here. There has been a dedicated session on that topic at Spring which will probably be released on InfoQ in a bit, where I actually go into that more deeply. There already is a recoded version from this year's Devoxx on YouTube.

    Spring Data REST has been a response to two things:

    1. People building REST APIs the same way over and over again on top of Spring Data repositories.
    2. People building what they call REST APIs in a very unsohisticated way: create a repository for every JPA entity in the system, expose a collection and item resource for that, hand the entity to Jackson, see what sticks. Throw some Swagger at it, be done.

    So we we're deriving two conclusions from that:

    1. We can help people build something better in the first place (using the knowledge about aggregates, leveraging hypermedia elements etc.)
    2. We can let people use that with way less boilerplate code.

    As you probably realize at this point is that the goal never was to create a framework that promises a turn-key, complete REST API, but a solid foundation for the boilerplate parts of what you want to build eventually.

    Imagine the following scenario: you have a team and 2 weeks of time to build a REST API you can now chose between 2 approaches:

    1. The team can go ahead and say: "Ah, it's all CRUD. JSON via HTTP", spend 1.5 weeks of implementing exactly that and then spend another half a week to throw Swagger on top of it to create URI based documentation. That sort of gets the job done but will incentivise building tightly coupled clients that break with every tiny change.
    2. You could have a team that's aware of the fact there will be parts of the API that follow the collection resource / item resource pattern, and — given a decent domain model — they can get those parts with the blink of an eye. They then actually have the time to think about what higher level API functionality they can expose, how they can leverage hypermedia to implement that functionality, reduce coupling by the client etc.

    Which of the two do you think will produce the better API?

    So the goal is to free people from the boilerplate for them to find time to think about the actually interesting parts of their APIs. And that is exactly what the RESTBucks example project mentioned in the presentation shows: simple stuff covered by SDR, all more advanced state transitions implemented manually. I'd go as far as stating that indeed, the least you make use of SDR the better as that hopefully means you get to APIs that deserve the term REST in the first place. But there shouldn't be any reason the more fundamental parts of that API need a lot of boilerplate code and don't behave like a proper hypermedia-driven resource.

  • Not pleasant REST API design.

    by welcomen wel,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Good speech, but, IMHO, I don't agree with your design concept.

    Firstly, presentation layer knows how to present (display) domain knowledge for user (any other kind of clients) to interact with the system is a different concept as mention about coupling presentation layer on domain layer implementation.

    Secondly, the trade off of your implementation (hypermedia REST) would not be a good news for your client teams because, you embed a UI specific (http) implementation into RESTful architecture -- the consumer side of a REST API is not aways a http protocol based client, for example, a iOS app or another service.

  • Re: Not pleasant REST API design.

    by Oliver Drotbohm,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Thanks for your comments. TBCH, I don't get the intent of your first statement. Would you mind to elaborate.

    I am not sure I can agree to your second claim either. The consumer of a REST API *is* — by definition an HTTP client (unless you want to include non-HTTP REST implementations into the picture). That means, the iOS app or any other client app *of course* is an HTTP client to the server. What else would it be?

  • Re: SDR encourages bad api design

    by le cuong,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I think that the concept that Oliver talking about here is quite similar to 1. & 2. points of the concept naked object, see en.wikipedia.org/wiki/Naked_objects

    That means business logic should be seen as domain objects, and all of these objects should be published. And actually domain objects in this case is not all small separate entities but they are normally aggregate.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT