Symfony로 외부 RESTful API를 사용하는 방법은 무엇입니까?


10

우리는 주로 프론트 엔드 Symfony 애플리케이션이 백엔드 RESTful API와 상호 작용하여 프로젝트를위한 마이크로 서비스 아키텍처를 구축하고 있습니다.

문제는이 접근 방식이 데이터베이스가있는 Doctrine에 크게 의존하는 Symfony 엔티티 관리를 위반한다는 것입니다. Symfony가 일반적으로 Doctrine으로 엔티티를 처리하여 대부분의 작업을 자동화하는 경우 API에서 외부 데이터에 액세스해야 할 때 쉽게 재현 할 수 없습니다.

예를 들어, 클라이언트 엔티티의 경우 :

  • Doctrine을 사용하면 Client 클래스를 정의하기 만하면됩니다. 이제 클라이언트를 쉽게 만들고 업데이트하고 검색 할 수 있습니다.
  • REST API 접근 방식을 사용하면 API를 통해 클라이언트에 액세스 할 수 있지만 클라이언트 생성 (POST), 업데이트 (PUT), 검색 (GET) 등을 정의하는 작업이 많이 있습니다.

클라이언트는 프런트 엔드 앱뿐만 아니라 전용 API와 같은 여러 응용 프로그램에서 사용됩니다.

API 호출 복잡성을 숨기고 모든 API 데이터를 로컬로 가져 와서 Doctrine 또는 다른 방법으로 액세스하는 엔티티와 유사한 메소드로 클래스를 작성해야합니까?


나는 당신과 같은 보트에 있습니다. OpenApi / Swagger 사양에서 생성 된 클라이언트와 외부 API를 소비합니다. 소비 '수명주기', 크루 드 작업, 매개 변수 및 필터 양식 생성에 대한 모범 사례가 궁금합니다. 현재 Symfony에 관계없이 모든 접근 방식을 포함하도록 검색을 확장하고 있습니다.
상류

몇 달 동안이 문제를 해결 하고이 질문으로 돌아간 지금까지 두 가지 답변 모두 비슷한 해결책을 제공합니다 : 포포로 API 호출 추상화. 그것이 다른 솔루션이 존재하지만 우리가 결국 사용했던 방식입니다. 비슷한 Webapp <> API 통신 컨텍스트에서 Webapp에서 API 호출을 숨기는 추상화 레벨을 사용하는 것이 좋은 솔루션 인 것 같습니다. 마이크로 서비스 및 API- 리드 접근 방식의 등장으로 일반적인 문제로 보이는 것을 해결하기 위해 관련 모범 사례 및 도구가 등장 할 것입니다.
Pierre B.

여기에서도 비슷한 접근 방식이 적용되었습니다. 비즈니스 로직은 이제 '액션'레이어에 포함되는데, 이는 REST API 또는이를 호출하는 cli 명령인지 상관하지 않습니다. 알리스 테어 콕번의 각형 디자인은 우리의 경우에 좋은 출발점이었다 alistair.cockburn.us/Hexagonal+architecture이
상류

답변:


2

외부 API (JSON)를 사용하는 심포니 기반 프로젝트를 만들었습니다. 내가 한 것은 자체 엔티티 세트 (POPO)로 독립 클라이언트 라이브러리 ( "클라이언트 라이브러리"-소프트웨어, 작곡가 패키지)를 만드는 것이 었습니다. Symfony에서 제공하는 인터페이스를 사용하여 프레임 워크와 통합합니다 (예 : 사용자 정의 사용자 제공자 작성 ).

클라이언트는 http 호출을 "비하인드 스토리"로 만듭니다. 이는 향후 테스트 기능에 중요합니다. 데이터 소스와 통신하는 방식을 공개하고 싶지 않으며 테스트가 라이브 API에 의존하기를 원하지 않습니다.

클라이언트 라이브러리 인터페이스 (예 : 어떻게 보이는지) :

class ApiClient {

   /**
    * @throws SomeApiException If credentials are invalid
    * @return ApiUser
    */
   public function authenticate($username, $password);

   /**
    * @return ApiUser
    */
   public function findUserByEmail($email);

   /**
    * @throws SomeApiException If email is invalid
    * @return void
    */
   public function changeUserEmail(User $user, $newEmail);
}

클라이언트 라이브러리는 내부적으로 통신을 위해 Guzzle을 사용하고 결과를 캐싱하기 위해 Doctrine Cache 구성 요소를 사용합니다. 엔터티 객체와 json 사이의 매핑은 한 번 작성된-매퍼에 의해 만들어졌으며, 자주 또는 이벤트가 전혀 바뀌지 않았습니다. 이 경우 JSON과의 자동 변환을 위해 JMS Serializer를 사용하는 것이 좋습니다 (JSON을 사용한다고 가정합니다).

Redis와 같은 좋은 캐싱 메커니즘과 로컬 스토리지가 필요합니다. 각 앱 요청에서 API 호출을 수행하면 서버가 종료되고 애플리케이션 속도가 크게 느려집니다. http 캐시 작동 방식을 이해하는 것이 매우 중요합니다. API가 캐싱 헤더를 사용하지 않거나 모호한 방식으로 사용하는 경우 변경 내용을 추적하기가 매우 어렵고 리소스를 많이 사용합니다.

또한 연결이 끊어지면 클라이언트가 어떻게 작동해야하는지 생각하고 싶을 것입니다. 클라이언트가 정지 된 데이터를 사용해야합니까? 앱과 API간에 프록시 서버를 사용하는 것이 좋습니다. 이 경우 프록시와 같은 프록시는 요청 속도를 높이고 앱 속도를 늦추지 않고 백그라운드에서 정지 된 데이터를 새로 고칠 수 있습니다. 또한 API 실패시 웹 사이트를 온라인 상태로 유지합니다. 그 동안에는 데이터를 쓰지 못할 수도 있지만 사용자는 여전히 캐시 된 데이터를 찾아 볼 수 있습니다.

교리에 관해서는 " 악기의 법칙 "을 참조하십시오 .


1

교리는 데이터베이스 액세스 계층입니다. 데이터베이스에 액세스하고 싶지는 않지만 API는 아닙니다. 여전히 엔티티를 만들 수 있지만 구현을 확장 할 필요가없는 간단한 객체 (popo)로 사용할 수 있습니다. 모든 CRUD 메소드를 구현하는 저장소가 있어야합니다. 이 경우 데이터베이스 대신 API를 호출하십시오. 이를위한 인터페이스를 만들었습니다. 마이크로 서비스가 응답하지 않을 수있는 모든 곳을 고려해야한다는 점을 제외하고는 응용 프로그램이 다르게 느껴질 필요는 없습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.