Spring Data Rest Mongo - how to create a DBRef using an id instead of a URI? - spring

I have the following entity, that references another entity.
class Foo {
String id;
String name supplierName;
**#DBRef** TemplateSchema templateSchema;
...
}
I want to be able to use the following JSON (or similar) to create a new entity.
{
"supplierName": "Stormkind",
"templateSchema": "572878138b749120341e6cbf"
}
...but it looks like Spring forces you to use a URI like this:
{
"supplierName": "Stormkind",
"templateSchema": "/template-schema/572878138b749120341e6cbf"
}
Is there a way to create the DBRef by posting an ID instead of a URI?
Thanks!

In REST, the only form of ID's that exist are URIs (hence the name Unique Resource Identifier). Something like 572878138b749120341e6cbf does not identify a resource, /template-schema/572878138b749120341e6cbf does.
On the HTTP level, entities do not exist, only resources identified by URIs. That's why Spring Data REST expects you to use URIs as identifiers.

Related

How to decide a type of GetMapping method in Spring boot?

I'm spring boot learner and trying to clone-code a website. Below is a code to get a data of the specific content.
#GetMapping("/api/articles/{id}")
public List<Article> takeArticle() { return articleRepository.findAllByOrderByModifiedAtDesc();}
Then the ARC shows whole data of contents which I've already posted, but I want a specific data according to the id value. I think the problem is the type of takeArticle() method. So which type should be used for the method above to fulfill my purpose?
#GetMapping("/api/articles/{id}")
public Article takeArticle(#PathVariable Integer id) {
return articleRepository.findById(id).orElseThrow(() -> {
// throw Not found exception if article doesn't exists with given id
});
}
By the way you shouldn't use repository interfaces directly in your controller layer. Use service layer between repository and controllers.

Which method does Spring Data Rest use to extract entity from query parameter?

For example, we have a request like this:
GET /orders/search
{
"user": "http://example.org/users/1",
...
}
In what way does Spring Data Rest retrieve the User Entity from an URL? Does it use Regex to retrieve the id 1 then query it or something else?
If yo are wondering about spring data repository, you need to use this method.
User user = userRepository.findById(Integer id);

How can i hide some attribute conditionally from json response

how can write condition 'if' type is no details other two fields are hide in json response. if possible i want to do it in pojo or bean ?
Using spring boot
spring data rest and hal.
pojo
MongoDB Repository
I want to show accountNo and Accountdetails if type="details"
{
"Name":"Json",
"lastName":"Amazon",
"type":"Details",
"accountNo":"12123",
"AccountdetailsDetails":[ some details]
}
If type="noDetails" just show mentioned response.
{
"Name":"Json",
"lastName":"Amazon",
"type":"NoDetails"
}
I guess you need #JsonFilter.
You can use this annotation to exclude some properties in your entity response.
What you need to do is Add this annotation with unique name in your entity file.
Then serialize this entity values using filter class SimpleFilterProvider.
Take a look on
https://www.logicbig.com/tutorials/misc/jackson/json-filter-annotation.html

Updating property and resource link in single PUT query with Spring Data Rest

OK so let's start self referencing object, something like this:
#Data
#Entity
public class FamilyNode {
#Id
#GeneratedValue
private long id;
private boolean orphan;
#ManyToOne
private FamilyNode parent;
}
And a standard repository rest resource like this:
#RepositoryRestResource(collectionResourceRel = "familynodes", path = "familynodes")
public interface FamilyNodeRepository extends CrudRepository<FamilyNode, Long> {
}
Now, let's assume some parent objects which I want to link with already exist with ID=1 and ID=2, each of which were created with a POST to /api/familynodes which looked like this:
{
"orphan": true,
}
If I attempt to create a new client (ID=3) with something like this using a POST request to /api/familynodes, it will work fine with the linked resource updating fine in the DB:
{
"orphan": false,
"parent": "/api/familynodes/1"
}
However, if I attempt to do a PUT with the following body to /api/familynodes/3, the parent property seems to silently do nothing and the database is not updated to reflect the new association:
{
"orphan": false,
"parent": "/api/familynodes/2"
}
Similarly (and this is the use case that I'm getting at), a PUT like this will only update the orphan property but will leave the parent untouched:
{
"orphan": true,
"parent": null
}
So you now have a record which claims to be an orphan, but still has a parent. Of course you could do subsequent REST requests to the resource URI directly but I'm trying to make rest operations atomic so that it's impossible for any single rest query to create invalid state. So now I'm struggling with how do that with what seems like a simple use case without getting into writing my own controller to handle it - am I missing a mechanism here within the realm of spring data rest?
This is the expected behaviour for PUT requests in Spring Data Rest 2.5.7 and above wherein a PUT request does not update the resource links, only the main attributes.
As detailed here by Oliver Gierke:
If we consider URIs for association fields in the payload to update those associations, the question comes up about what's supposed to happen if no URI is specified. With the current behavior, linked associations are simply not a part of the payload as they only reside in the _links block. We have two options in this scenario: wiping the associations that are not handed, which breaks the "PUT what you GET" approach. Only wiping the ones that are supplied using null would sort of blur the "you PUT the entire state of the resource".
You may use a PATCH instead of PUT to achieve the desired result in your case

create object from class name as string in ruby

I have a model source (name, url, method)
The program parses the source's url for data. Now I have differen classes for parsing different types of urls: rss, xml, ogdata ...
So I have a common interface
new(url) //Parses the url
getTitle() //Get the title of the data
getPrice() //Get the price
And I have four classes rss, xml, ogdata. These classes are in seperate files. The idea is to add more classes as I discover different types of pages. I want to initiate the right classes for the url.
method=source.method
//NOw I want to create a new class of the name specified in method
parser=Rss.new(source.url)//Instead of this
//Something like
parser=.new(source.url)
You can try using const_get.
Ex:-
Kernel.const_get("YourClassNameHere").new
*Kernel.const_get("YourClassNameHere")* will get you the class. And you can use it to instantiate new instances of the class.
irb(main):081:0> User.name
=> "User"
then
"User".constantize.new(name: 'David')
or
User.name..constantize.new(name: 'David')

Resources