2017-02-17 9 views
1

Как настроить Spring Data Rest для сериализации связанных объектов напрямую?данные весеннего остатка сериализуют ассоциации в качестве связанного объекта

Я хочу, чтобы это выглядело так: Обратите внимание, что ссылка «владелец» относится к объекту «account».

{ 
    "name" : "customer", 
    "_links" : { 
    "self" : { 
     "href" : "http://localhost:8081/api/v1/servers/1005" 
    }, 
    "owner" : { 
     "href" : "http://localhost:8081/api/v1/account/100" 
    } 
    } 
} 

В настоящее время (по умолчанию) связаны связанные объекты (ака, ассоциации), сериализованные косвенно.

Я НЕ хочу, чтобы это выглядело так: ссылка владельца была через сущность самосервера.

{ 
    "name" : "customer", 
    "_links" : { 
    "self" : { 
     "href" : "http://localhost:8081/api/v1/servers/1005" 
    }, 
    "owner" : { 
     "href" : "http://localhost:8081/api/v1/servers/1005/owner" 
    } 
    } 
} 

Я проверил документы и не могу найти упоминаний о том, чтобы идти по «прямому» маршруту.

+1

как вы создаете ссылки, что вы имеете в виду с * по умолчанию *? – linqu

+0

Использование Spring Boot и аннотации @RepositoryRestController. – sofend

ответ

1

Решено с взломом.

Шаги:

  1. Добавить в @RestResource(exported = false) в ассоциации по лицу.
  2. Зарегистрировать ResourceProcessor<Resource<OwnedEntity>>@Bean (OwnedEntity - мой базовый класс для объектов, имеющих владельца) и изменить коллекцию ссылок в этом методе.

Данные находятся в Customizing the JSON output section of the Spring Data REST reference docs.

By Request, вот код, который делает это:

/* 
* Copyright (c) 2017. DataVolo, Inc. All Rights Reserved. 
*/ 

package com.datavolo.tenant.web; 

import com.datavolo.tenant.domain.Account; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.data.rest.webmvc.support.RepositoryEntityLinks; 
import org.springframework.hateoas.Link; 
import org.springframework.hateoas.mvc.ResourceAssemblerSupport; 
import org.springframework.stereotype.Component; 

import javax.annotation.Nonnull; 

/** 
* 
*/ 
@Component 
public class AccountResourceAssembler extends ResourceAssemblerSupport<Account, AccountResource> { 

    private final RepositoryEntityLinks repositoryEntityLinks; 

    @Autowired 
    public AccountResourceAssembler(@Nonnull RepositoryEntityLinks repositoryEntityLinks) { 
     super(AccountController.class, AccountResource.class); 
     this.repositoryEntityLinks = repositoryEntityLinks; 
    } 

    @Override 
    public AccountResource toResource(Account entity) { 
     Link accountLink = repositoryEntityLinks.linkToSingleResource(Account.class, entity.getId()); 
     String accountHref = accountLink.getHref(); 
     Link selfLink = new Link(accountHref, Link.REL_SELF); 

     Link subAccounts = new Link(accountHref + "/subAccounts", "subAccounts"); 
     Link owner = new Link(accountHref + "/owner", "owner"); 

     Account parent = entity.getParent(); 
     Link[] links; 
     if (parent == null) { 
      links = new Link[] {selfLink, accountLink, subAccounts, owner}; 
     } else { 
      Link parentAccountLink = repositoryEntityLinks.linkToSingleResource(Account.class, parent.getId()); 
      Link parentLink = new Link(parentAccountLink.getHref(), "parent"); 
      links = new Link[] {selfLink, accountLink, subAccounts, owner, parentLink}; 
     } 

     return new AccountResource(entity, links); 
    } 
} 

Это затем получает вводит в контроллер (снабженный @RepositoryRestController), что, в свою очередь, генерируют ответ.

В этой системе у нас есть общий базовый класс для контроллеров, и у нас есть настройка с несколькими арендаторами, где все нетривиальные объекты без поиска (например, все, что хранит системные данные) ссылаются прямо или косвенно объект учетной записи, который контролирует и представляет аренду. Поэтому мы делаем это в одном месте для одного объекта, и все готово. Другие ссылки более ручные, и со временем мы в основном просто пожали плечами и оставили выход Spring HATEOS по умолчанию как есть, и пусть клиенты приспосабливаются к нему. Мы меняем это только в том случае, когда по умолчанию обычно происходит многократная обратная связь с бэкэнд - что является основной проблемой с этим способом, с которым Spring имеет дело с этим. Но это компромисс. Значение Spring по умолчанию не должно вызывать дополнительных накладных расходов, когда сам ресурс back-end объявляется как лениво разрешенная ссылка. Хорошим дополнением к этому было бы умение использовать эти ресурсы, чтобы те, которые уже были получены, напрямую ссылаются на их собственный идентификатор в ответе REST.

+0

Любой пример этого, особенно, как вы конвертируете из одного типа ссылки в другой? – cranphin

+0

Обновлен ответ с помощью примера кода. НТН. – sofend

+0

Если это сработает для вас, вам будет предложено повышение. – sofend

Смежные вопросы