Comments (29)
Jon,
any news on this topic?
from spring-data-rest.
In a REST context the URI is the identifier (hence the name Unique Resource Identifier). If there's a business key inside the entity on the domain class (like a customer id or the like) I wouldn't wanna use this as primary key actually. So we decided to keep the technical id out of the representation.
The primary reason is the following: if the representation contains the backend id of the entity - let's assume "1" - and you'd issue a PUT request to /entities/3, which entity would get updated? Would the entity with id 1 (as identified by the URI) get updated to get an id of 3? Should we silently ignore the id field? I think you get the point. Resource identification is done through URIs only.
from spring-data-rest.
Hi Oliver,
all right got that point. But what I don't understand is, why should id (as PK) and self entites/id differ? According to the code, the PK is always used to be included in the URI.
Besides that it is clear that the URI, is always the primary identifier but only for the REST stuff. In case of some application internal logic I would not want to use the whole URI at all. And additionally: as long as the user follows the HATEOAS principles and only uses the links for CRUD operations I don't see any disadvantage?
Sorry Oliver, I am still not confident with this.
from spring-data-rest.
A REST client does not know about a PK. It also doesn't know about it being encoded in the URI. Essentially that we use the PK in the URI is a URI design decision to make them readable easily. This comes with the side effect that to someone seeing the URI easily being able to get it's structure and generally being able to defer URIs to other resources. The crucial point is: a REST client is not aware of that. All it knows is that there's a rel of self
which identifies the resource. Putting technical identifiers into the representation just create incentives to construct URIs manually.As I mentioned: it's perfectly fine to have business identifiers in the representation but that is defined in the media type. That must not interfere with the way the client and the server identify resources.
Yet another question to emphasize what I am shooting for: we also don't just add the PK of a related resource into the representation additionally so why would you with the PK of the resource you get the current representation for.
from spring-data-rest.
Perhaps we are talking past each other: But in my opinion the argumentation contradicts itself. First you say the REST client does not know about a PK and you just use them to make them easily readable, which means, you could have chosen/choose in future a different one. Following this argumentation, the REST client is not allowed to rely on a specific property for REST stuff as the primary key to build URIs manually. Using the primary key would in this case violate the architecture.
If you conclude this approach, id is just a normal property as all others are. Removing it makes it to a property with a special purpose and the PK. For me these are two different layers:
- Layer One is application internal logic which might be based on the id property or whatever you might call it
- Layer Two is the communication internal logic, receiving, save and deleting entities, only relying on the links.
Each of them should be independent of each other and should not add restrictions for cases, in which the user might possibly use it against all architectural principles.
from spring-data-rest.
If you conclude this approach, id is just a normal property as all others are. Removing it makes it to a property with a special purpose and the PK.
I think you're mixing up cause and effect here. A PK is some property artificially introduced to the server side model of a domain concept. Taking it a step back it's even as follows: you have domain concepts. Some of these concepts have a lifecycle which by definition makes them an entity. As you need to identify those to keep track of the lifecycle, you introduce an identifier. Now here's the trick: to make sure you can separate between actual domain properties and the ones introduced technical reason I'd recommend not to mixup business identifiers with technical ones.
So I think the following design approach is pretty consistent:
- On the server side entities get a technical identifier to be able to be persisted into a store of that kind
- On a REST interface - by definition - resources are identified by their URIs
Thus why would you expose the server side store identifier? This is actually leaking implementation details. You could argue it is as the PK is part of the URI already. But that's an orthogonal URI design decision which ultimately doesn't even have to be the case. You could expose customers via /customers/{customerId}
where customerId
is not the PK.
REST is not about CRUD on entities or exposing entities 1:1 to the web.
from spring-data-rest.
I think you're mixing up cause and effect here. A PK is some property artificially introduced to the server side model of a domain concept. Taking it a step back it's even as follows: you have domain concepts. Some of these concepts have a lifecycle which by definition makes them an entity.
I am aware of that. It was just used as placeholder for "resource identifier". And I do understand your argumentation, but unless I think it is not a matter of architecture than just more a matter of taste.
Thus why would you expose the server side store identifier?
There are two reasons:
- You answered it yourself it is exposed anyway via URI
- Extracting it from the URI into the identifier for each object is totally uncomfortable. No one likes to loop through all Links and search for Self to get the identifier just for client side comparison. That's not only uncomfortable but also increases execution time as you always need to get Self out of links.
Regarding my last post as well I need to correct myself:
What we face are actually three layers:
- Server side (identified through PK of the entity model)
- Communication side (identified through the URI)
- Client side (now identified through the URI, but totally uncomfortable to use for client side logic with JavaScript for example)
As we have both arguments for and against it, I think the best way to handle this would be making the REST identifiers optionally included in the response body. By default it is turned off and if user likes to enable it, he needs to adjust some setting in the configuration.
from spring-data-rest.
- Extracting it from the URI into the identifier for each object is totally uncomfortable. No one likes to loop through all Links and search for Self to get the identifier just for client side comparison. That's not only uncomfortable but also increases execution time as you always need to get Self out of links.
That's my point: you would not do that in any case as this assumes the client knows that the URI contains a different kind of identifier which it must not. So you'd either compare URIs or some arbitrary off-band identifier like a customer number.
As we have both arguments for and against it, I think the best way to handle this would be making the REST identifiers optionally included in the response body. By default it is turned off and if user likes to enable it, he needs to adjust some setting in the configuration.
That might be the case but I clearly vote a -1 on this one as it just breaks well-established principles in information hiding and pretty much breaks the abstraction purpose of a REST interface.
So I think we end up on agreeing to disagree on this one, which is perfectly fine :). Good reference discussion in any case!
from spring-data-rest.
That might be the case but I clearly vote a -1 on this one as it just breaks well-established principles in information hiding and pretty much breaks the abstraction purpose of a REST interface.
Ok I would vote + 1 and the rest could decide! :-)
So I think we end up on agreeing to disagree on this one, which is perfectly fine :). Good reference discussion in any case!
Indeed to both :-).
from spring-data-rest.
Since this would be really useful to integrate spring data rest with most client-side libs, those well-established principles seem a bit ivory-towerish to me ;-).
A huge +1 from my part. In fact, I've made it work by simply adding to org.springframework.data.rest.webmvc.EntityToResourceConverter a quick hack at the end of the convert method:
@Override public Resource convert(Object source) { ... //hack to serialize the ID of the entity AttributeMetadata idAttribute=entityMetadata.idAttribute(); if(idAttribute!=null){ Object val= entityMetadata.idAttribute().get(source); Object name=idAttribute.name(); if(val!=null && name!=null){ entityDto.put(entityMetadata.idAttribute().name(),val); } } // END Hack return new EntityResource(entityDto, links);
from spring-data-rest.
I'd argue this is implementing HTTP as it is specified. Of course, people also have built web applications piping non-idempotent operations through get request for ages and called that "pragmatic". Arguing that this was plain wrong can of course be considered "ivory tower", I'd call it "back to the spec". Same applies to IDs in representations: HTTP has a concept of an ID, it's called URI. If you build a remoting protocol on top of HTTP, why would you deliberately abuse it? You're not going to build a second SOAP, are you? ;)
However, no one is going to prevent you from hacking the feature into the library, simply don't expect us to advocate breaking the abstraction :). Let's agree to disagree and move on…
from spring-data-rest.
I knew this discussion would arise again. :-)
Nice solution Manuel, will perhaps use it as well!
from spring-data-rest.
By the way, how do you propose to resolve having access the entity ID without the rest of the URI on the client-side? URI parsing?
Would be nice to have a pet-store sample app that shows us how to "go back to the spec", for illustration purposes as well as to ensure that spring data rest is useful for the real world...
regards
from spring-data-rest.
Do you have some news about this issue ? Indeed, I want to make a javascript client side application and it would be very nice to have this id returned in the response to use hateoas Rest web service directly.
Thx
from spring-data-rest.
In the latest snapshots (and the upcoming version 1.1) you can configure whether or not you want an entity's ID exposed. The setting is not global, but it can be used (judiciously).
from spring-data-rest.
Thank you, so I look forward to the next release. is there any release date sheduled ?
from spring-data-rest.
Thanks Oliver for pointing me to this discussion.
I think URI as an identifier is meant to enable communication over HTTP and should not intrude on internals of both server as well as client. Like the id is important for server as PK, clients also use it extensively as unique identifier and is an internal to the client implementation. How would you suggest client to identify the resource uniquely otherwise, for eg. ids to be used in html, for javascript logic? Of course client could generate its own identifier, but why bother since there is already a common way to handle it through ids? Hypermedia is supposed to guide the client in making valid state transfer requests on available resource, not hiding the id.
+1 and can I know when the next release with this flexibility would be available as mentioned in one of the posts?
from spring-data-rest.
@deepakpol: Just go ask yourself, what is the ID of the resource you fetched? That's what you use as id on the client side. Everything else is baking server side knowledge into the client, which you want to avoid. REST is not about Javascript (frameworks). I'd be incredibly hesitant to let requirements (especially that contradict or work around the underlying principles of your remoting technology) your JS library imposes into the design of your server side implementation / representation.
from spring-data-rest.
I would say, I totally agree about the REST Hateoas principle about the URI as ID but, with JS framework like angular or BackBone, the id in the model client side drives the http request (POST,PUT..) to create or update model server side.
Furthermore, the rooting with # (hashbang mode) is more difficult without these ids (get #1].
Hiding the id doesn't help to develop RIA with these kind of frameworks, I wanted to use spring hateoas but, finally, I have created some REST WS just with Spring MVC to not add complexity in my project.
Maybe someone gets a successful experience with angular/backbone on Hateoas WS.
from spring-data-rest.
@deepakpol @fgaujous The latest SD REST 1.1 includes a configuration option in RepositoryRestConfiguration that allows you to expose the id value for a domain object. It's done on a case-by-case basis.
from spring-data-rest.
@jbrisbin thank you, I will try it.
from spring-data-rest.
@fgaujous I must admit I had a long discussion with @olivergierke as well regarding the Ids, which I thought need to be exposed for client side frameworks. I am not able to tell you anything about Backbone, but I am using AngularJS for 6 months now. In my first trials had serious issues without the Ids. Then I created a service, which takes care about the Id and resource handling. And I must tell you I don't need any Id in the service.
from spring-data-rest.
@fgaujous Care to elaborate in how far its so terribly difficult for Angular/Backbone to work with URIs as IDs? Shouldn't it be totally opaque to the framework whether it uses a "1" or a "http://whatever.com/foo/1" or even an MD5 hash of the latter if you prefer to "hide" the URI structure and want to work with hex strings?
I think it's terribly amusing that your client side javascript framework defines how to reference data. :)
from spring-data-rest.
@olivergierke that's a matter of perspective. Others may see SD REST just as the data provider for the real product build in rock-solid Javascript. :-)
from spring-data-rest.
@jhiemer Ok, Do you have somewhere an example with a service which takes care about the id and resource handling. ?
Concerning @olivergierke answer, what is the way you choose to manage it ? URIs as ids ?
Thank you.
from spring-data-rest.
@jhiemer - That's not the point. You've decided to use HTTP to access data, thus it's good practice to adhere to the concepts of it. And identity of resources is defined to be URIs in HTTP. You don't choose to ride by bike and complain about the missing steering wheel, do you?
@fgaujous - That shows the entire dilemma… it's not "URIs as ids", a URI is an id… Unique Resource Identifier… I think it can't be more to the point.
from spring-data-rest.
The main issue here is third party client side libraries that assume the URL for a resources is basePath + identifier
. There is a lot of code that bakes in this old assumption. I'll have to plead guilt as the RestStore in rest.js also follows this anti-pattern. Time to fix that...
from spring-data-rest.
@scothis If I talk about backbone (and pretty sure other libraries too), it does provide a default implementation with some assumptions about URL creation. However, I don't think that is totally correct and restrictive either. The framework is not restrictive and you can always use links embedded in the resource to transfer the states by overriding the behavior if the service provider supports hypermedia.
I understand the URL should be the unique identifier of the resource, but I don't think it has to be represented as "id" field, IMHO that is a some assumption which becomes restrictive to the server. I would say keeping URL to the resource in id field and as a 'self' link sounds redundant to me. If the client is going to use links to discover and follow next possible states, what use case would make them use the URL in id field? I think id should be considered as just another property of the representation and server should be allowed to transfer that
@jbrisbin thanks, I look forward to trying that out.
from spring-data-rest.
@deepakpol library users will often take the path of least resistance, it's the lib's responsibility to make doing the right thing the easiest path.
I didn't mean to sugest that the URI should be stored in a property with the literal name 'id', but that the URI should be used as the identifier for the resource. Having the URI in a resource twice would indeed be redundant. Having a link with a rel self is sufficient. A good library should be configurable to know where to find the ID, whether it be a property named 'id' or a self link.
from spring-data-rest.
Related Issues (20)
- Release 4.3 M2 (2024.0.0)
- Json object not gettting captured in POST request HOT 4
- Upgrade to Spring Security 6.1.7 for integration tests
- Release 4.1.11 (2023.0.11)
- Release 4.2.5 (2023.1.5)
- Release 4.3 RC1 (2024.0.0)
- Upgrade to MongoDB driver 5
- Upgrade to Hibernate 6.5.0.CR1
- Release 4.1.12 (2023.0.12)
- Release 4.2.6 (2023.1.6)
- Release 4.3 GA (2024.0.0)
- [FEATURE REQUEST]: Spring Data JPA Support for Apache Delta Lake HOT 1
- Document error codes for ItemResources HOT 2
- Release 4.2.7 (2023.1.7)
- Release 4.3.1 (2024.0.1)
- Release 4.4 M1 (2024.1.0)
- [Question] Understanding links generated by Spring Data Rest HOT 1
- Support record for projections
- Release 4.2.8 (2023.1.8)
- Release 4.3.2 (2024.0.2)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spring-data-rest.