Spring Data REST Как добавить встроенные ресурсы inline

Я использую Spring Data REST и Hateoas в сочетании с браузером HAL. Это работает отлично, но теперь я хотел бы сделать JSON-дамп определенной сущности с (набором) связанных с ней объектов. я использовал@Projection но потом я снова застрял.

К вашему сведению: Нормальное поведение (со встроенными ссылками и т. Д.) Должно сохраняться помимо новой конечной точки (без встроенных ссылок и ссылок).

Чтобы проиллюстрировать мою проблему / вопрос:

class Person {
  String name;
  List<Company> companies;
}

class Company {
  String name;
  Address address;
}

class Address {
  String street;
}

Теперь я хотел бы увидеть что-то вроде этого:

{
   "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/#projections-excerpts

В моем примере я представил две трудности, которые у меня есть: списки (компании) и несколько уровней: person-> company-> address. Оба должны работать (вероятно, 5 уровней, некоторые из которых имеют «много» отношений).

 M. Deinum29 июн. 2016 г., 13:19
Вы можете, не используя Spring Data REST. Spring Data Rest принимает взвешенное мнение о том, как правильно делать отдых, и это включает ссылки на отношения вместо полной сущности.
 codesmith29 июн. 2016 г., 17:21
Спасибо, Дейн. Spring Data Rest находится на пути к классам и должен оставаться там. Ваш комментарий еще применим?
 robie201107 сент. 2018 г., 09:19
другие способы встраивания значений связанных объектов:stackoverflow.com/a/52217253/2248405

Ответы на вопрос(3)

что лучший способ встроить List или HashMap - это преобразовать его в строку json и обратно в объект java, когда вы читаете его ....

это можно легко сделать используя

    @Convert(converter = PluginAnalyzerConfigConverter.class)
  private PluginAnalyzerConfig configuration;
//in Entity Class

// declare a converter class like this
public class PluginAnalyzerConfigConverter implements
    AttributeConverter<PluginAnalyzerConfig, String> {

  @Override public String convertToDatabaseColumn(PluginAnalyzerConfig config) {
    Gson parser = new Gson();
    return parser.toJson(config, PluginAnalyzerConfig.class);
  }

  @Override public PluginAnalyzerConfig convertToEntityAttribute(String source) {
    Gson parser = new Gson();
    return parser.fromJson(source, PluginAnalyzerConfig.class);
  }
}

как показано наSpring Data с Mysql JSON-типом

У нас есть нечто подобное в Spring Data DynamoDb - для AWS DynamoDB

как вы определили. Прогнозы всегда встроены, поэтому один из вариантов - создать прогнозы для каждой из ваших сущностей и объединить их следующим образом:

@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 элементы, но вы получите вложенность, которую вы хотите:

{
  "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 а такжеAddress сущности как остальные ресурсы, вы можете пометить их хранилища@RepositoryRestResource(exported=false)и они будут встроены везде, где на них ссылаются, без какой-либо необходимости в проекциях.

Однако последнее замечание - этот запрос несколько противоречит идеалам Spring Data REST и Spring HATEOAS и предлагает большие, громоздкие запросы с проблемой n + 1. Помните, что Spring Data REST - это не готовое решение для превращения модели предметной области в API, и рендеринг глубинных графов объектов (если это ваше намерение) потенциально может представлять собой конечную точку настраиваемого контроллера на временной основе, где вы может тщательно контролировать условия.

если вам не нужны ссылки, у вас должен быть контроллер и ресурс, где вы сопоставляете данные с ресурсом и возвращаете коллекцию ресурса из контроллера.

 codesmith30 июн. 2016 г., 14:19
Это может затем стать проблематичным, когда отношения также указывают на другой путь (от Адреса к Компании и от Компании к Человеку. Подход, не связанный с упругостью данных, покажет все (бесконечный рекурсивный цикл).@JsonIgnore в этом случае не вариант, потому что тогда представление hatoas будет отображаться неправильно. Я еще не проверял это, но это кажется мне логичным.
 codesmith29 июн. 2016 г., 17:22
Спасибо, Фахад, но не могли бы вы проиллюстрировать, что вы имеете в виду? Вы имеете в виду@Controller и@Resource или больше в общем? Как это отображение данных работает с вашей точки зрения?
 Fahad Fazil29 июн. 2016 г., 17:30
Под ресурсом я имею в виду класс, который похож на сущность с нужной вам информацией. Вы можете использовать dozer bean mapper для отображения данных на ресурс.

Ваш ответ на вопрос