@ryanF의 탁월한 답변 외에도 약간 더 자세하게 설명하고 싶습니다.
사용자 지정 엔터티에 대한 리포지토리를 추가해야하는 이유를 요약하고이를 수행하는 방법을 설명하고 해당 리포지토리 메서드를 웹 API의 일부로 노출하는 방법도 설명하고 싶습니다.
면책 조항 : 제 3 자 모듈에 대해이 작업을 수행하는 방법에 대한 실용적인 접근 방식 만 설명하고 있습니다. 핵심 팀에는 자체 표준이 있습니다 (또는 그렇지 않음).
일반적으로 저장소의 목적은 스토리지 관련 논리를 숨기는 것입니다.
리포지토리의 클라이언트는 반환 된 엔터티가 배열의 메모리에 유지되는지, MySQL 데이터베이스에서 검색되는지, 원격 API 또는 파일에서 가져 왔는지 상관하지 않습니다.
나는 Magento 핵심 팀이 나중에 ORM을 변경하거나 교체 할 수 있도록 이것을했다고 가정합니다. Magento에서 ORM은 현재 모델, 리소스 모델 및 컬렉션으로 구성되어 있습니다.
타사 모듈이 리포지토리 만 사용하는 경우 Magento는 데이터 저장 방법 및 위치를 변경할 수 있으며 이러한 깊은 변경에도 불구하고 모듈은 계속 작동합니다.
저장소는 일반적으로 같은 방법이 findById()
, findByName()
, put()
또는 remove()
.
마 젠토에서이 일반적이라고합니다 getbyId()
, save()
그리고 delete()
심지어 그들이 무엇을하고 있지만, CRUD DB 작업을하는 척.
Magento 2 리포지토리 방법은 API 리소스로 쉽게 노출 될 수 있으므로 타사 시스템 또는 헤드리스 Magento 인스턴스와의 통합에 유용합니다.
"사용자 지정 엔터티에 대한 리포지토리를 추가해야합니까?".
언제나 그렇듯이 대답은
"그것은 달려있다".
간단히 말해서, 다른 모듈에서 엔티티를 사용한다면 저장소를 추가하고 싶을 것입니다.
마 젠토 2에서 리포지토리는 웹 API, 즉 REST 및 SOAP 리소스로 쉽게 노출 될 수 있습니다.
타사 시스템 통합 또는 헤드리스 Magento 설정으로 인해 이것이 흥미로울 경우, 다시 엔터티에 대한 리포지토리를 추가하고 싶을 것입니다.
사용자 지정 엔터티에 대한 리포지토리를 어떻게 추가합니까?
REST API의 일부로 엔티티를 노출한다고 가정하십시오. 그렇지 않은 경우, 인터페이스 작성에 대한 다음 부분을 건너 뛰고 바로 아래의 "저장소 및 데이터 모델 구현 작성"으로 이동할 수 있습니다.
저장소 및 데이터 모델 인터페이스 작성
Api/Data/
모듈 에서 폴더 를 만듭니다 . 이것은 단지 컨벤션이므로 다른 위치를 사용할 수는 있지만 그렇게해서는 안됩니다.
저장소는 Api/
폴더 로 이동 합니다. Data/
하위 디렉토리는 나중에이다.
에서 Api/
, 노출 할 방법과 PHP 인터페이스를 만들 수 있습니다. Magento 2 규칙에 따르면 모든 인터페이스 이름은 접미사로 끝납니다 Interface
.
예를 들어 Hamburger
엔터티의 경우 인터페이스를 만듭니다 Api/HamburgerRepositoryInterface
.
리포지토리 인터페이스 만들기
마 젠토 2 리포지토리는 모듈의 도메인 로직의 일부입니다. 즉, 저장소가 구현해야하는 고정 된 메소드 세트가 없습니다.
전적으로 모듈의 목적에 달려 있습니다.
그러나 실제로 모든 리포지토리는 매우 유사합니다. CRUD 기능을위한 래퍼입니다.
대부분의 방법이 getById
, save
, delete
와 getList
.
예를 들어 CustomerRepository
has 메소드 가있을 수 있습니다. 이 메소드 get
는 이메일 getById
로 고객을 가져 와서 엔티티 ID로 고객을 검색하는 데 사용됩니다.
햄버거 엔터티에 대한 예제 리포지토리 인터페이스는 다음과 같습니다.
<?php
namespace VinaiKopp\Kitchen\Api;
use Magento\Framework\Api\SearchCriteriaInterface;
use VinaiKopp\Kitchen\Api\Data\HamburgerInterface;
interface HamburgerRepositoryInterface
{
/**
* @param int $id
* @return \VinaiKopp\Kitchen\Api\Data\HamburgerInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function getById($id);
/**
* @param \VinaiKopp\Kitchen\Api\Data\HamburgerInterface $hamburger
* @return \VinaiKopp\Kitchen\Api\Data\HamburgerInterface
*/
public function save(HamburgerInterface $hamburger);
/**
* @param \VinaiKopp\Kitchen\Api\Data\HamburgerInterface $hamburger
* @return void
*/
public function delete(HamburgerInterface $hamburger);
/**
* @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
* @return \VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface
*/
public function getList(SearchCriteriaInterface $searchCriteria);
}
중대한! 여기에 타임 싱크가 있습니다!
여기에 잘못되면 디버깅하기 어려운 몇 가지 문제가 있습니다.
- REST API에 연결하려는 경우 PHP7 스칼라 인수 유형 또는 리턴 유형을 사용 하지 마십시오 !
- 모든 인수에 대한 PHPDoc 주석과 모든 메소드에 리턴 유형을 추가하십시오!
- PHPDoc 블록에서 정규화 된 클래스 이름 을 사용하십시오 !
주석은 Magento Framework에서 구문 분석하여 JSON 또는 XML과의 데이터 변환 방법을 결정합니다. 클래스 가져 오기 (즉, use
명령문)는 적용되지 않습니다!
모든 메소드에는 인수 유형과 리턴 유형이있는 주석이 있어야합니다. 메소드가 인수를 취하지 않고 아무것도 리턴하지 않더라도 주석이 있어야합니다.
/**
* @return void
*/
스칼라 유형 ( string
, int
, float
및 bool
)도 인수와 반환 값으로 모두 지정해야합니다.
위의 예에서 객체를 반환하는 메서드에 대한 주석도 인터페이스로 지정됩니다.
리턴 유형 인터페이스는 모두 Api\Data
네임 스페이스 / 디렉토리에 있습니다.
이는 비즈니스 로직이 포함되어 있지 않음을 나타냅니다. 그들은 단순히 데이터의 가방입니다.
다음에 이러한 인터페이스를 만들어야합니다.
DTO 인터페이스 생성
Magento는 이러한 인터페이스를 "데이터 모델"이라고 부릅니다.
이 유형의 클래스는 일반적으로 데이터 전송 개체 또는 DTO라고 합니다.
이 DTO 클래스에는 모든 속성에 대한 getter 및 setter 만 있습니다.
데이터 모델보다 DTO를 선호하는 이유는 ORM 데이터 모델, 리소스 모델 또는 뷰 모델과 혼동하기가 쉽지 않기 때문입니다. 이미 너무 많은 것이 Magento의 모델입니다.
리포지토리에 적용되는 PHP7 타이핑과 관련하여 동일한 제한 사항이 DTO에도 적용됩니다.
또한 모든 메소드에는 모든 인수 유형과 리턴 유형이있는 주석이 있어야합니다.
<?php
namespace VinaiKopp\Kitchen\Api\Data;
use Magento\Framework\Api\ExtensibleDataInterface;
interface HamburgerInterface extends ExtensibleDataInterface
{
/**
* @return int
*/
public function getId();
/**
* @param int $id
* @return void
*/
public function setId($id);
/**
* @return string
*/
public function getName();
/**
* @param string $name
* @return void
*/
public function setName($name);
/**
* @return \VinaiKopp\Kitchen\Api\Data\IngredientInterface[]
*/
public function getIngredients();
/**
* @param \VinaiKopp\Kitchen\Api\Data\IngredientInterface[] $ingredients
* @return void
*/
public function setIngredients(array $ingredients);
/**
* @return string[]
*/
public function getImageUrls();
/**
* @param string[] $urls
* @return void
*/
public function setImageUrls(array $urls);
/**
* @return \VinaiKopp\Kitchen\Api\Data\HamburgerExtensionInterface|null
*/
public function getExtensionAttributes();
/**
* @param \VinaiKopp\Kitchen\Api\Data\HamburgerExtensionInterface $extensionAttributes
* @return void
*/
public function setExtensionAttributes(HamburgerExtensionInterface $extensionAttributes);
}
메소드가 배열을 검색하거나 리턴하는 경우 배열의 항목 유형을 PHPDoc 주석에 지정하고 여는 닫는 대괄호를 지정해야 []
합니다.
이는 스칼라 값 (예 :) int[]
과 객체 (예 :) 모두에 해당됩니다 IngredientInterface[]
.
Api\Data\IngredientInterface
객체 배열을 반환하는 메소드에 대한 예제로를 사용하고 있습니다.이 포스트 터프에 재료 코드를 추가하지는 않습니다.
ExtensibleDataInterface?
위의 예 HamburgerInterface
에서 ExtensibleDataInterface
.
기술적으로 이것은 다른 모듈이 엔티티에 속성을 추가 할 수있게하려는 경우에만 필요합니다.
그렇다면 getExtensionAttributes()
and 라는 규칙에 따라 다른 getter / setter 쌍을 추가해야합니다 setExtensionAttributes()
.
이 메소드의 리턴 유형 이름은 매우 중요합니다!
Magento 2 프레임 워크는 인터페이스의 이름, 구현 및 팩토리를 생성합니다. 이러한 메커니즘의 세부 사항은이 게시물의 범위를 벗어납니다.
확장 가능하게 만들려는 객체의 인터페이스가 호출 \VinaiKopp\Kitchen\Api\Data\HamburgerInterface
되면 확장 속성 유형은이어야 \VinaiKopp\Kitchen\Api\Data\HamburgerExtensionInterface
합니다. 따라서 단어 Extension
는 엔터티 이름 Interface
뒤에 접미사 바로 앞에 삽입해야합니다 .
엔터티를 확장 할 수 없게하려면 DTO 인터페이스가 다른 인터페이스를 확장 할 필요가 없으며 getExtensionAttributes()
및 setExtensionAttributes()
메소드를 생략 할 수 있습니다.
지금은 DTO 인터페이스에 대한 정보가 충분합니다. 이제 리포지토리 인터페이스로 돌아갑니다.
getList () 리턴 유형 SearchResults
저장소 메소드 getList
는 또 다른 유형, 즉 SearchResultsInterface
인스턴스 를 리턴 합니다.
이 메소드 getList
는 물론 지정된와 일치하는 객체 배열을 SearchCriteria
반환 SearchResults
할 수 있지만 인스턴스를 반환하면 유용한 메타 데이터를 반환 된 값에 추가 할 수 있습니다.
저장소 getList()
메소드 구현 에서 아래에서 작동 방식을 확인할 수 있습니다 .
햄버거 검색 결과 인터페이스의 예는 다음과 같습니다.
<?php
namespace VinaiKopp\Kitchen\Api\Data;
use Magento\Framework\Api\SearchResultsInterface;
interface HamburgerSearchResultInterface extends SearchResultsInterface
{
/**
* @return \VinaiKopp\Kitchen\Api\Data\HamburgerInterface[]
*/
public function getItems();
/**
* @param \VinaiKopp\Kitchen\Api\Data\HamburgerInterface[] $items
* @return void
*/
public function setItems(array $items);
}
이 인터페이스는 두 가지 메소드 getItems()
와 setItems()
상위 인터페이스 의 유형을 대체합니다 .
인터페이스 요약
이제 다음과 같은 인터페이스가 있습니다.
\VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface
\VinaiKopp\Kitchen\Api\Data\HamburgerInterface
\VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface
저장소는 아무것도 확장하지
(가) HamburgerInterface
를 확장 \Magento\Framework\Api\ExtensibleDataInterface
,
그리고는 HamburgerSearchResultInterface
을 확장합니다 \Magento\Framework\Api\SearchResultsInterface
.
저장소 및 데이터 모델 구현 작성
다음 단계는 세 가지 인터페이스의 구현을 만드는 것입니다.
리포지토리
본질적으로 리포지토리는 ORM을 사용하여 작업을 수행합니다.
getById()
, save()
및 delete()
방법은 매우 정직하고 있습니다.
은 HamburgerFactory
이하에서 좀 알 수있는 바와 같이, 생성자 인수 저장소로 주입된다.
public function getById($id)
{
$hamburger = $this->hamburgerFactory->create();
$hamburger->getResource()->load($hamburger, $id);
if (! $hamburger->getId()) {
throw new NoSuchEntityException(__('Unable to find hamburger with ID "%1"', $id));
}
return $hamburger;
}
public function save(HamburgerInterface $hamburger)
{
$hamburger->getResource()->save($hamburger);
return $hamburger;
}
public function delete(HamburgerInterface $hamburger)
{
$hamburger->getResource()->delete($hamburger);
}
이제 저장소의 가장 흥미로운 부분 인 getList()
방법입니다. 방법은 번역하는 컬렉션에 메소드 호출에 조건.
getList()
SerachCriteria
그 까다로운 부분은 점점 AND
및 OR
수집에 조건을 설정하기위한 구문 그것이 EAV 또는 평평한 테이블 엔티티인지 여부에 따라 상이하다 특히 이후, 우측 필터에 대한 조건.
대부분의 경우 getList()
아래 예와 같이 구현할 수 있습니다.
<?php
namespace VinaiKopp\Kitchen\Model;
use Magento\Framework\Api\SearchCriteriaInterface;
use Magento\Framework\Api\SortOrder;
use Magento\Framework\Exception\NoSuchEntityException;
use VinaiKopp\Kitchen\Api\Data\HamburgerInterface;
use VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface;
use VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterfaceFactory;
use VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface;
use VinaiKopp\Kitchen\Model\ResourceModel\Hamburger\CollectionFactory as HamburgerCollectionFactory;
use VinaiKopp\Kitchen\Model\ResourceModel\Hamburger\Collection;
class HamburgerRepository implements HamburgerRepositoryInterface
{
/**
* @var HamburgerFactory
*/
private $hamburgerFactory;
/**
* @var HamburgerCollectionFactory
*/
private $hamburgerCollectionFactory;
/**
* @var HamburgerSearchResultInterfaceFactory
*/
private $searchResultFactory;
public function __construct(
HamburgerFactory $hamburgerFactory,
HamburgerCollectionFactory $hamburgerCollectionFactory,
HamburgerSearchResultInterfaceFactory $hamburgerSearchResultInterfaceFactory
) {
$this->hamburgerFactory = $hamburgerFactory;
$this->hamburgerCollectionFactory = $hamburgerCollectionFactory;
$this->searchResultFactory = $hamburgerSearchResultInterfaceFactory;
}
// ... getById, save and delete methods listed above ...
public function getList(SearchCriteriaInterface $searchCriteria)
{
$collection = $this->collectionFactory->create();
$this->addFiltersToCollection($searchCriteria, $collection);
$this->addSortOrdersToCollection($searchCriteria, $collection);
$this->addPagingToCollection($searchCriteria, $collection);
$collection->load();
return $this->buildSearchResult($searchCriteria, $collection);
}
private function addFiltersToCollection(SearchCriteriaInterface $searchCriteria, Collection $collection)
{
foreach ($searchCriteria->getFilterGroups() as $filterGroup) {
$fields = $conditions = [];
foreach ($filterGroup->getFilters() as $filter) {
$fields[] = $filter->getField();
$conditions[] = [$filter->getConditionType() => $filter->getValue()];
}
$collection->addFieldToFilter($fields, $conditions);
}
}
private function addSortOrdersToCollection(SearchCriteriaInterface $searchCriteria, Collection $collection)
{
foreach ((array) $searchCriteria->getSortOrders() as $sortOrder) {
$direction = $sortOrder->getDirection() == SortOrder::SORT_ASC ? 'asc' : 'desc';
$collection->addOrder($sortOrder->getField(), $direction);
}
}
private function addPagingToCollection(SearchCriteriaInterface $searchCriteria, Collection $collection)
{
$collection->setPageSize($searchCriteria->getPageSize());
$collection->setCurPage($searchCriteria->getCurrentPage());
}
private function buildSearchResult(SearchCriteriaInterface $searchCriteria, Collection $collection)
{
$searchResults = $this->searchResultFactory->create();
$searchResults->setSearchCriteria($searchCriteria);
$searchResults->setItems($collection->getItems());
$searchResults->setTotalCount($collection->getSize());
return $searchResults;
}
}
안의 연산자 FilterGroup
는 OR 연산자를 사용하여 결합해야합니다 .
논리 AND 연산자를 사용하여 별도의 필터 그룹을 결합합니다 .
휴
이것은 가장 큰 일이었습니다. 다른 인터페이스 구현이 더 간단합니다.
DTO
Magento는 원래 개발자가 DTO를 엔터티 모델과 별개의 별도 클래스로 구현하도록 의도했습니다.
핵심 팀은 비록 고객 모듈 (위해 이런 짓을 \Magento\Customer\Api\Data\CustomerInterface
하여 구현됩니다 \Magento\Customer\Model\Data\Customer
,하지 \Magento\Customer\Model\Customer
).
다른 모든 경우 엔터티 모델은 DTO 인터페이스를 구현합니다 (예 : \Magento\Catalog\Api\Data\ProductInterface
로 구현 \Magento\Catalog\Model\Product
).
나는 핵심 팀원들에게 회의에서 이것에 대해 물었지만, 좋은 연습으로 여겨 질 것이 무엇인지에 대한 명확한 대답을 얻지 못했습니다.
내 추천은이 추천이 취소되었다는 것입니다. 그래도 공식적인 진술을 얻는 것이 좋을 것입니다.
지금은 모델을 DTO 인터페이스 구현으로 사용하기위한 실용적인 결정을 내 렸습니다. 별도의 데이터 모델을 사용하는 것이 더 깨끗하다고 생각되면 자유롭게 사용하십시오. 두 방법 모두 실제로 잘 작동합니다.
DTO 인터페이스 Magento\Framework\Api\ExtensibleDataInterface
가를 확장하면 모델이 확장되어야 Magento\Framework\Model\AbstractExtensibleModel
합니다.
확장성에 신경 쓰지 않으면 모델은 단순히 ORM 모델 기본 클래스를 계속 확장 할 수 있습니다 Magento\Framework\Model\AbstractModel
.
예제가 있기 때문에 HamburgerInterface
확장 ExtensibleDataInterface
햄버거 모델은 확장 AbstractExtensibleModel
여기에서 알 수있는 바와 같이, :
<?php
namespace VinaiKopp\Kitchen\Model;
use Magento\Framework\Model\AbstractExtensibleModel;
use VinaiKopp\Kitchen\Api\Data\HamburgerExtensionInterface;
use VinaiKopp\Kitchen\Api\Data\HamburgerInterface;
class Hamburger extends AbstractExtensibleModel implements HamburgerInterface
{
const NAME = 'name';
const INGREDIENTS = 'ingredients';
const IMAGE_URLS = 'image_urls';
protected function _construct()
{
$this->_init(ResourceModel\Hamburger::class);
}
public function getName()
{
return $this->_getData(self::NAME);
}
public function setName($name)
{
$this->setData(self::NAME, $name);
}
public function getIngredients()
{
return $this->_getData(self::INGREDIENTS);
}
public function setIngredients(array $ingredients)
{
$this->setData(self::INGREDIENTS, $ingredients);
}
public function getImageUrls()
{
$this->_getData(self::IMAGE_URLS);
}
public function setImageUrls(array $urls)
{
$this->setData(self::IMAGE_URLS, $urls);
}
public function getExtensionAttributes()
{
return $this->_getExtensionAttributes();
}
public function setExtensionAttributes(HamburgerExtensionInterface $extensionAttributes)
{
$this->_setExtensionAttributes($extensionAttributes);
}
}
속성 이름을 상수로 추출하면 한 곳에 유지할 수 있습니다. getter / setter 쌍과 데이터베이스 테이블을 작성하는 Setup 스크립트에서도 사용할 수 있습니다. 그렇지 않으면 상수로 추출 할 때 이점이 없습니다.
SearchResult
이것은 SearchResultsInterface
프레임 워크 클래스에서 모든 기능을 상속 할 수 있기 때문에 구현할 세 가지 인터페이스 중 가장 단순합니다.
<?php
namespace VinaiKopp\Kitchen\Model;
use Magento\Framework\Api\SearchResults;
use VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface;
class HamburgerSearchResult extends SearchResults implements HamburgerSearchResultInterface
{
}
ObjectManager 환경 설정 구성
구현이 완료되었지만 Magento Framework 개체 관리자가 사용할 구현을 알지 못하므로 인터페이스를 다른 클래스의 종속성으로 계속 사용할 수 없습니다. etc/di.xml
환경 설정으로 구성 을 추가해야합니다 .
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface" type="VinaiKopp\Kitchen\Model\HamburgerRepository"/>
<preference for="VinaiKopp\Kitchen\Api\Data\HamburgerInterface" type="VinaiKopp\Kitchen\Model\Hamburger"/>
<preference for="VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface" type="VinaiKopp\Kitchen\Model\HamburgerSearchResult"/>
</config>
리포지토리를 API 리소스로 어떻게 노출 할 수 있습니까?
이 부분은 정말 간단합니다. 인터페이스, 구현 및 인터페이스를 만드는 모든 작업을 수행 한 것에 대한 보상입니다.
etc/webapi.xml
파일을 작성하기 만하면됩니다.
<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<route method="GET" url="/V1/vinaikopp_hamburgers/:id">
<service class="VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface" method="getById"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
<route method="GET" url="/V1/vinaikopp_hamburgers">
<service class="VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface" method="getList"/>
<resources>
<resource ref="anonymouns"/>
</resources>
</route>
<route method="POST" url="/V1/vinaikopp_hamburgers">
<service class="VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface" method="save"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
<route method="PUT" url="/V1/vinaikopp_hamburgers">
<service class="VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface" method="save"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
<route method="DELETE" url="/V1/vinaikopp_hamburgers">
<service class="VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface" method="delete"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
</routes>
이 구성은 저장소를 REST 엔드 포인트로 사용할 수있을뿐만 아니라 메소드를 SOAP API의 일부로 노출합니다.
첫 번째 경로 예 <route method="GET" url="/V1/vinaikopp_hamburgers/:id">
에서 자리 표시 :id
자는 인수 이름과 매핑 된 메서드를 일치시켜야합니다 public function getById($id)
. 메소드 인수 variable name이 (가) 있으므로
두 이름이 일치해야합니다 (예 : /V1/vinaikopp_hamburgers/:hamburgerId
작동하지 않음) $id
.
이 예제에서는 접근성을로 설정했습니다 <resource ref="anonymous"/>
. 즉, 리소스가 제한없이 공개적으로 노출됩니다!
로그인 한 고객 만 리소스를 사용할 수있게하려면을 사용하십시오 <resource ref="self"/>
. 이 경우 me
자원 엔드 포인트 URL 의 특수 단어 를 사용 $id
하여 현재 로그인 한 고객의 ID로 인수 변수를 채 웁니다 .
젠토 고객에서보세요 etc/webapi.xml
그리고 CustomerRepositoryInterface
당신이 필요합니다.
마지막으로을 <resources>
사용하여 리소스에 대한 액세스를 관리자 계정으로 제한 할 수도 있습니다. 이를 위해 <resource>
ref를 etc/acl.xml
파일에 정의 된 식별자로 설정 하십시오.
예를 들어 <resource ref="Magento_Customer::manage"/>
고객 관리 권한이있는 모든 관리자 계정에 대한 액세스를 제한합니다.
curl을 사용하는 예제 API 쿼리는 다음과 같습니다.
$ curl -X GET http://example.com/rest/V1/vinaikopp_hamburgers/123
참고 :이 글을 https://github.com/astorm/pestle/issues/195에 대한 답변으로 시작
했습니다. pestle을 확인하고 Commercebug를 구입 하여 @alanstorm 의 후원자가 되십시오.