programing

Spring HATEOAS에서 "_embedded" 속성을 삭제하는 방법

lastcode 2023. 2. 18. 20:14
반응형

Spring HATEOAS에서 "_embedded" 속성을 삭제하는 방법

REST API를 구축하기 위해 Spring Boot과 HATEOAS를 사용하고 있으며, API가 컬렉션을 반환하면 다음과 같이 "_embedded" 속성에 래핑됩니다.

{
   "_links":{
      "self":{
         "href":"http://localhost:8080/technologies"
      }
   },
   "_embedded":{
      "technologies":[
         {
            "id":1,
            "description":"A",
            "_links":{
               "self":{
                  "href":"http://localhost:8080/technologies/1"
               }
            }
         },
         {
            "id":2,
            "description":"B",
            "_links":{
               "self":{
                  "href":"http://localhost:8080/technologies/2"
               }
            }
         }
      ]
   }
}

다음과 같은 응답을 원합니다.

{
   "_links":{
      "self":{
         "href":"http://localhost:8080/technologies"
      }
   },
   "technologies":[
      {
         "id":1,
         "description":"A",
         "_links":{
            "self":{
               "href":"http://localhost:8080/technologies/1"
            }
         }
      },
      {
         "id":2,
         "description":"B",
         "_links":{
            "self":{
               "href":"http://localhost:8080/technologies/2"
            }
         }
      }
   ]
}

My Technologies 컨트롤러:

@RestController
@ExposesResourceFor(Technology.class)
@RequestMapping(value = "/technologies")
public class TechnologiesController {
    ...
    @ResquestMapping(method = RequestMethod.GET, produces = "application/vnd.xpto-technologies.text+json")
    public Resources<Resource<Technology>> getAllTechnologies() {
        List<Technology> technologies = technologyGateway.getAllTechnologies();
        Resources<<Resource<Technology>> resources = new Resources<Resource<Technology>>(technologyResourceAssembler.toResources(technologies));
        resources.add(linkTo(methodOn(TechnologiesController.class).getAllTechnologies()).withSelfRel());
        return resources;
    }

구성 클래스에는 @EnableHypermediaSupport(유형 = EnableHypermediaSupport)라는 주석이 있습니다.하이퍼미디어 타입HAL)

'_embedded' 없이 응답을 생성하는 가장 좋은 방법은 무엇입니까?

설명서에 기재되어 있는 바와 같이

응용 프로그램/hal+json 응답을 응용 프로그램/json을 받아들이는 요청으로 전송해야 합니다.

생략하기 위해서_embedded응답에 추가가 필요합니다.

spring.hateoas.use-hal-as-default-json-media-type=false

로.application.properties.

restTemplate에서 Resources/Resource를 사용하기 어렵기 때문에 HAL 기능을 종료합니다.이 기능을 무효로 하려면 , 다음의 코드를 사용합니다.

public class SpringRestConfiguration implements RepositoryRestConfigurer {
    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {

        config.setDefaultMediaType(MediaType.APPLICATION_JSON);
        config.useHalAsDefaultJsonMediaType(false);
    }
}

저는 좋아요.restTemplate에서 더 많은 지원이 있으면 HAL이 좋습니다.

추가Accept요청 헤더:

Accept : application/x-spring-data-verbose+json

Spring Data를 사용하고 있으며, 이를 문제로 간주하는 사용자에게 해결책은

spring.data.rest.defaultMediaType = application/json

응용 프로그램 속성에 있습니다.링크는 계속 사용할 수 있지만 _embedded는 더 이상 없습니다.

산출된 결과와 예상된 결과에서 설명하는 것은 의미론적으로 다른 것입니다.전자는, 다음의 HAL 표현입니다.Collection<Technology>후자는 다음을 나타냅니다.

class Wrapper {
  Resources<Technology> technologies;
}

이것이, 실제로 톱 레벨의 작성 방법에 주의해 주세요.technologies응답에 표시할 속성입니다.컨트롤러에서는 후자를 작성하지 않습니다.톱 레벨Resources인스턴스는 기본적으로 컬렉션이며 HAL에서 최상위 컬렉션을 나타내는 유일한 방법은_embedded원하지 않는 것처럼 보이지만 컨트롤러 방식에는 그렇게 기재되어 있습니다.

만약 당신이Wrapper, 다음과 같은 것이 동작합니다(테스트되지 않음).

Wrapper wrapper = new Wrapper(assembler.toCollectionModel(technologies);
EntityModel<Wrapper> model = EntityModel.of(wrapper);
model.add(linkTo(…));

PS: 봄 HATEOAS 1.0부터ResourcesCollectionModel그리고.ResourceEntityModel.

이 코드를 서비스에서 사용할 수 있습니다.

  constructor(
    private httpClient: HttpClient
  ) { }

  retrieveAllStudents(){
    return this.httpClient.get<any[]>(`http://localhost:8080/students`);
  }

Json의 _embedded 부분을 처리하고 원하는 데이터를 추출합니다.

export class ListStudentsComponent implements OnInit {

 // declaring variables to be used
  student: Student;
  students: Student[];
  message: string;

  // injecting student service into the constuctor
   constructor(
    private studentService: StudentService,
  ) { }

  ngOnInit() {
    this.refreshStudents();
  }
refreshStudents(){
  this.studentService.retrieveAllStudents().subscribe(
     response => {
       console.log(response);
      this.students = response._embedded.students as Student[];
     }
   );
 }

언급URL : https://stackoverflow.com/questions/28808220/how-to-remove-the-embedded-property-in-spring-hateoas

반응형