Spring Data REST如何在线添加嵌入式资源 [英] Spring Data REST How to add embedded resources inline
问题描述
我正在将Spring Data REST和Hateoas与HAL浏览器结合使用。这非常有效,但是现在我想用一组特定实体对其关联对象进行JSON转储。我使用 @Projection
然后我再次陷入困境。
I'm using Spring Data REST and Hateoas in combination with HAL browser. This works perfectly, but now I would like to make a JSON dump of a specific entity with (a set of) its associated objects. I used @Projection
but then I got stuck again.
FYI:正常行为(包含嵌入式和链接等) )应该保留在新端点之外(没有嵌入和链接)。
FYI: The normal behaviour (with embedded and links etc) should remain besides the new endpoint (without embedded and links).
进一步说明我的问题/问题:
To further illustrate my problem/question:
class Person {
String name;
List<Company> companies;
}
class Company {
String name;
Address address;
}
class Address {
String street;
}
现在我希望看到类似的内容:
Now I would like to see something like this:
{
"name": "John",
"companies": [
{
"name": "Stackoverflow",
"address": {"street": "Highway blvd."}
},
{
"name": "Oracle",
"address": {"street": "Main rd."}
}
]
}
我收到这个:
{
"name": "John",
"_links": {
"self": {"href": "http...."},
"companies": {"href": "http ..."}
},
}
参见: http://docs.spring.io/ spring-data / rest / docs / current / reference / html / #project-摘录
在我的例子中,我介绍了两个困难:列表(公司) nies)和多个级别:person-> company-> address。两者都需要工作(可能有5个级别,其中一些级别有'很多')。
In my example I introduced two difficulties I have: Lists (companies) and multiple levels: person->company->address. Both are required to work (probably 5 levels, some of which have 'many' relations).
推荐答案
可接受的内联方法正如您所确定的那样,实体是预测。投影总是内联的,因此一个选项是为每个实体创建投影并将其组合如下:
The accepted method of inlining entities is projections, as you identified. Projections are always inlined, so one option is to create projections for each of your entities and combine them like so:
@Projection(name = "personProjection", types = Person.class)
public interface PersonProjection {
String getFirstName();
List<CompanyProjection> getCompanies();
}
@Projection(name = "companyProjection", types = Company.class)
public interface CompanyProjection {
String getName();
AddressProjection getAddress();
}
@Projection(name = "addressProjection", types = Address.class)
public interface AddressProjection {
String getStreet();
}
A GET people / 1? projection = personProjection
仍将呈现 _links
元素,但您将获得所需的嵌套:
A GET people/1?projection=personProjection
will still render _links
elements, but you will get the nesting you want:
{
"companies" : [ {
"address" : {
"street" : "123 Fake st",
"_links" : {
"self" : {
"href" : "http://localhost:8080/addresses/1{?projection}",
"templated" : true
}
}
},
"name" : "ACME inc.",
"_links" : {
"self" : {
"href" : "http://localhost:8080/companies/1{?projection}",
"templated" : true
},
"address" : {
"href" : "http://localhost:8080/companies/1/address"
}
}
} ],
"firstName" : "Will",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
},
"person" : {
"href" : "http://localhost:8080/people/1{?projection}",
"templated" : true
},
"companies" : {
"href" : "http://localhost:8080/people/1/companies"
}
}
}
或者,如果您不需要将 Company
和地址
实体公开为休息资源,你可以用 @RepositoryRestResource(exported = false)
标记它们的存储库,它们将被引入,不需要任何投影。
Alternatively, if you don't need to expose the Company
and Address
entities as rest resources, you can mark their repositories with @RepositoryRestResource(exported=false)
, and they will be inlined wherever they are referenced, without any need for projections.
尽管有一个最后的警告 - 这个请求在某种程度上与Spring Data REST和Spring HATEOAS的精神作斗争,并邀请遭遇n + 1问题的大型,笨拙的查询。请记住,Spring Data REST不是将域模型转换为API的交钥匙解决方案,并且渲染深层对象图(如果这是您的意图)可能是您可能在临时基础上作为自定义控制器端点公开的内容可以彻底控制条件。
A final caveat, though - this request is somewhat fighting against the ethos of Spring Data REST and Spring HATEOAS, and inviting big, unwieldy queries suffering the n+1 problem. Remember that Spring Data REST is not a turnkey solution for turning a domain model into an API, and rendering deep object graphs (if that is your intention) is potentially something you might expose as a custom controller endpoint on an ad-hoc basis where you can control the conditions thoroughly.
这篇关于Spring Data REST如何在线添加嵌入式资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!