Spring HATEOS - Как спроектировать все атрибуты класса базового типа? - PullRequest
0 голосов
/ 08 февраля 2019

Учитывая проекцию для данного класса, есть ли способ сообщить Spring, чтобы он включал все атрибуты по умолчанию класса, определенного в types аннотации Projection ?

Учитывая 2 класса сущности

@Entity 
@Data 
public class Client {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String nom;
    private String adresseLigne1;
    private String adresseLigne2;
    private String ville;

    @ManyToOne
    private Province province; 
    /* Many other attribute */

}

и

@Entity
@Data
public class Province {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String name;
}

и репозиторий для каждого

@RepositoryRestResource(collectionResourceRel = "Client", path = "Client")
public interface ClientRepository extends PagingAndSortingRepository<Client, Long> {
    List<Client> findBy();
}

-

@RepositoryRestResource(collectionResourceRel = "Province", path = "Province")
public interface ProvinceRepository extends PagingAndSortingRepository<Province, Long> {
    List<Province> findByName(String name);
}

Я получаю следующий json по умолчанию для клиента:

{
  "nom" : "Mallowpond High",
  "adresseLigne1" : "895 Gonçal Burg",
  "adresseLigne2" : "Apt. 450",
  "ville" : "Lake Irenehaven",
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108"
    },
    "province" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
    }
  }
}

Есть ли способ создать проекцию, которая бы возвращала все атрибуты клиента без необходимостизапишите все методы getXXX для всех атрибутов в Client

@Projection(name = "inlineProvince", types = { Client.class })
public interface ClientProjection {
    /* A way to tell the projection to include all of Client attribute */
    Province getProvince();  // This is the linked object I want to add to my json output as an in-line map (i.e have the behaviour as if it did not have it's own Repository)
}

, чтобы при вызове http://127.0.0.1:8080/api/rest/Client/108?projection=inline:

* можно было встроить провинцию в мой клиент JSON1034 *

Я обнаружил, что могу сделать:

@Projection(name = "inline", types = { Client.class })
public interface ClientProjection {
    @Value("#{target}") 
    Client getClient();
    Province getProvince();  // This is the linked object I want to add to my json output as an in-line map (i.e have the behaviour as if it did not have it's own Repository)
}

, но в качестве верхнего элемента я получаю и клиента, и провинцию.т.е. провинция не в клиенте:

{
  "province" : {
    "name" : "quebec"
  },
  "client" : {
      "nom" : "Mallowpond High",
      "adresseLigne1" : "895 Gonçal Burg",
      "adresseLigne2" : "Apt. 450",
      "ville" : "Lake Irenehaven",
      "_links" : {
        "self" : {
          "href" : "http://127.0.0.1:8080/api/rest/Client/108"
        },
        "province" : {
          "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
        }
      }
  }
}

1 Ответ

0 голосов
/ 10 февраля 2019

То, что производит @RestRepositoryResource, называется форматом HAL.То, что вы спрашиваете, отличается от спецификации HAL, и я бы предложил придерживаться стандарта (по очевидным причинам).

В HAL есть поддержка встраивания отношений в ресурс.Это будет означать, что у вас получится поле _embedded, в котором будет храниться набор мощности 1 с провинцией.Это выглядело бы примерно так:

{
  "nom" : "Mallowpond High",
  "adresseLigne1" : "895 Gonçal Burg",
  "adresseLigne2" : "Apt. 450",
  "ville" : "Lake Irenehaven",
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108"
    },
    "province" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
    }
  },
  "_embedded"{
     "provinces" : [{
        "name" : "Quebec",
        "_links" : {
          "self" : {
            "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
          }
        }
     }]
  }
}

К сожалению, это не так просто поддерживается с помощью Spring * @RepositoryRestResource, но все же относительно легко достигается.Вам нужно будет добавить ResourceAssembler и преобразовать Client в ClientResource, который поддерживает поле _embedded.Посмотрите на этот вопрос как вы можете это сделать (я тоже этим пользуюсь)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...