@RyanF'ın mükemmel cevabına ek olarak biraz daha ayrıntılı bilgi vermek istiyorum.
Özel varlıklar için bir depo ekleme nedenlerini özetlemek, bunun nasıl yapılacağına örnekler vermek ve ayrıca bu depo yöntemlerinin Web API'sinin bir parçası olarak nasıl gösterileceğini açıklamak istiyorum.
Feragatname: Yalnızca üçüncü parti modüller için bunun nasıl yapılacağı ile ilgili pratik bir yaklaşımı tarif ediyorum - çekirdek ekiplerin takip ettikleri (ya da değil) kendi standartları var.
Genel olarak, bir deponun amacı, depolamaya ilişkin mantığı gizlemektir.
Bir deponun müşterisi, geri gönderilen varlığın bir dizide bellekte tutulması, bir MySQL veritabanından alınması, uzak bir API'den veya bir dosyadan getirilmesi ile ilgilenmemelidir.
Magento'nun çekirdek ekibinin bunu yaptığını ve gelecekte ORM'yi değiştirebileceklerini veya değiştirebileceklerini farz ediyorum. Magento'da ORM şu anda Modeller, Kaynak Modelleri ve Koleksiyonlardan oluşmaktadır.
Üçüncü taraf bir modül yalnızca depoları kullanırsa, Magento verilerin nasıl ve nerede depolandığını değiştirebilir ve bu derin değişikliklere rağmen modül çalışmaya devam eder.
Depoları genellikle gibi yöntemleri var findById()
, findByName()
, put()
veya remove()
.
Magento Bu sık denir getbyId()
, save()
ve delete()
hatta onlar başka bir şey yapıyor ama CRUD DB işlemleri vardır davranarak,.
Magento 2 depo yöntemleri kolayca API kaynakları olarak gösterilebilir, böylece onları üçüncü parti sistemler veya başsız Magento örnekleri ile entegrasyon için değerli kılar.
"Özel varlığım için bir depo eklemeli miyim?"
Her zamanki gibi, cevap
"Değişir".
Uzun lafın kısası, eğer varlıklarınız diğer modüller tarafından kullanılacaksa, o zaman evet, muhtemelen bir depo eklemek istersiniz.
Burada sayılan başka bir faktör daha var: Magento 2'de, depolar kolayca Web API'sı (REST ve SOAP - kaynakları) olarak gösterilebilir.
Eğer üçüncü parti sistem entegrasyonları veya başsız bir Magento kurulumundan dolayı bu sizin için ilginçse, o zaman tekrar, evet, muhtemelen varlığınız için bir depo eklemek istersiniz.
Özel varlığım için nasıl bir havuz eklerim?
Varlığınızı REST API’nin bir parçası olarak göstermek istediğinizi varsayalım. Eğer bu doğru değilse, arayüzleri oluşturma konusundaki yaklaşan kısmı atlayabilir ve aşağıdaki "Depo ve veri modeli uygulamasını oluştur" seçeneğine doğrudan gidebilirsiniz.
Havuz ve veri modeli arayüzleri oluşturun
Api/Data/
Modülünüzdeki klasörleri oluşturun . Bu sadece kongredir, farklı bir konum kullanabilirsiniz, ancak kullanmamalısınız.
Depo Api/
klasöre gider . Alt Data/
dizin daha sonra içindir.
Içinde Api/
, göstermek istediğiniz yöntemlerle bir PHP arayüzü oluşturun. Magento 2 konvansiyonlarına göre, tüm arayüz isimleri sonek ile biter Interface
.
Mesela bir Hamburger
varlık için arayüzü yaratacağım Api/HamburgerRepositoryInterface
.
Havuz arayüzü oluştur
Magento 2 depoları bir modülün etki alanı mantığının bir parçasıdır. Bu, bir havuzun uygulaması gereken sabit bir yöntem seti olmadığı anlamına gelir.
Tamamen modülün amacına bağlıdır.
Bununla birlikte, pratikte tüm depolar oldukça benzerdir. CRUD işlevselliği için sarmalayıcılar.
Çoğu yöntemleri var getById
, save
, delete
ve getList
.
Dahası, örneğin bir müşteriyi e-posta yoluyla alan ve böylece bir müşteriyi işletme kimliği ile almak için kullanılan CustomerRepository
bir yöntem vardır . get
getById
Bir hamburger işletmesi için örnek bir depo arayüzü:
<?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);
}
Önemli! İşte timesinks ol!
Burada yanlış yaparsanız hata ayıklamak zor olan birkaç getcha var:
- DO NOT kullanmak PHP7 REST API içine bu kanca istiyorsanız sayıl argüman türlerini veya dönüş türleri!
- Tüm değişkenlere PHPDoc ek açıklamaları ve tüm yöntemlere dönüş türlerini ekleyin!
- PHPDoc bloğunda Tam Nitelikli Sınıf Adları kullanın !
Açıklamalar, verilerin JSON veya XML'den nasıl dönüştürüleceğini belirlemek için Magento Çerçevesi tarafından ayrıştırılır. Sınıf ithalatı (yani use
ifadeler) uygulanmaz!
Her yöntemin, herhangi bir argüman tipine ve dönüş tipine sahip bir ek açıklaması olmalıdır. Bir yöntem argüman almasa ve hiçbir şey döndürmezse bile, ek açıklamaya sahip olması gerekir:
/**
* @return void
*/
Sayısal tiplerin ( string
, int
, float
ve bool
) de bağımsız değişkenler için ve bir geri dönüş değeri olarak, her ikisi de belirtilmelidir gerekir.
Yukarıdaki örnekte, nesneleri döndüren yöntemlere ilişkin ek açıklamaların da arabirimler olarak belirtildiğini unutmayın.
Dönüş tipi arabirimlerinin tümü Api\Data
isim / dizin içindedir.
Bu, herhangi bir iş mantığı içermediklerini belirtmek içindir. Onlar sadece veri torbasıdır.
Daha sonra bu arayüzleri oluşturmalıyız.
DTO arayüzü oluşturun
Bence Magento, bu arayüzleri "veri modelleri" olarak adlandırıyor, hiç sevmediğim bir isim.
Bu sınıf türü genellikle Veri Aktarım Nesnesi veya DTO olarak bilinir .
Bu DTO sınıfları sadece tüm özellikleri için alıcılara ve ayarlayıcılara sahiptir.
DTO'yu veri modeli üzerinden kullanmayı tercih etmemin nedeni, ORM veri modelleri, kaynak modelleri veya görünüm modelleri ile karıştırılmasının daha az kolay olması ... zaten çok fazla şey Magento'da bulunan modellerdir.
Depolara uygulanan PHP7 tipleme ile ilgili aynı kısıtlamalar DTO'lar için de geçerlidir.
Ayrıca, her yöntemin, tüm argüman tiplerine ve dönüş tipine bir ek açıklaması olması gerekir.
<?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);
}
Bir yöntem bir diziyi alır veya döndürürse, dizideki öğelerin türünün PHPDoc ek açıklamasında ve ardından bir açılış ve kapanış köşeli parantez içinde belirtilmesi gerekir []
.
Bu, hem skaler değerler (örneğin int[]
) hem de nesneler (örneğin IngredientInterface[]
) için geçerlidir.
Api\Data\IngredientInterface
Bir nesne dizisi döndüren bir yöntem için bir örnek olarak kullandığımı , bileşenlerin kodunu bu yazıya zorlamayacağım.
ExtensibleDataInterface?
Yukarıdaki örnekte, HamburgerInterface
uzanır ExtensibleDataInterface
.
Teknik olarak, bu yalnızca, diğer modüllerin varlığınıza özellikler ekleyebilmesini istiyorsanız gereklidir.
Öyleyse, getExtensionAttributes()
ve adında kongre ile başka bir alıcı / ayarlayıcı çifti eklemeniz gerekir setExtensionAttributes()
.
Bu yöntemin dönüş türünün isimlendirilmesi çok önemlidir!
Magento 2 çerçevesi, haklı olarak isimlendirirseniz, uygulama için arayüzü, uygulamayı ve fabrikayı üretecektir. Bu mekaniğin detayları bu yazının kapsamı dışında.
Sadece, genişletilebilir yapmak istediğiniz nesnenin arayüzü çağrılırsa \VinaiKopp\Kitchen\Api\Data\HamburgerInterface
, extension niteliğinin type olması gerekir \VinaiKopp\Kitchen\Api\Data\HamburgerExtensionInterface
. Bu yüzden, kelimenin Extension
ismin Interface
sonundan hemen önce eklenmesi gerekir.
Varlığınızın genişletilebilir olmasını istemiyorsanız, DTO arayüzü başka herhangi bir arayüzü genişletmek zorunda değildir ve getExtensionAttributes()
ve setExtensionAttributes()
yöntemleri atlanabilir.
Şimdilik DTO arayüzü hakkında yeterli, depo arayüzüne geri dönme zamanı.
GetList () dönüş türü SearchResults
Havuz yöntemi getList
, başka bir tür, yani bir SearchResultsInterface
örnek döndürür .
Metot getList
elbette sadece belirtilenlerle eşleşen bir nesne dizisi döndürür SearchCriteria
, ancak bir SearchResults
örnek döndürmek döndürülen değerlere bazı yararlı meta veriler eklenmesini sağlar.
Bunun depo getList()
yöntemi uygulamasında aşağıda nasıl çalıştığını görebilirsiniz .
Örnek hamburger arama sonucu arayüzü:
<?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);
}
Tüm bu arabirim, iki yöntem getItems()
ve setItems()
ana arabirimin türlerini geçersiz kılar .
Arayüzlerin özeti
Şimdi aşağıdaki arayüzlere sahibiz:
\VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface
\VinaiKopp\Kitchen\Api\Data\HamburgerInterface
\VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface
Depo, hiçbir şey uzanır uzanır ,
ve genişletir .
HamburgerInterface
\Magento\Framework\Api\ExtensibleDataInterface
HamburgerSearchResultInterface
\Magento\Framework\Api\SearchResultsInterface
Havuz ve veri modeli uygulamaları oluşturma
Bir sonraki adım, üç arayüzün uygulamalarını oluşturmaktır.
Havuz
Temelde, depo ORM'yi işini yapmak için kullanır.
getById()
, save()
Ve delete()
yöntemler oldukça yalındır vardır. Aşağıda daha biraz görülebileceği gibi, bir yapıcı bağımsız değişken olarak depo içine enjekte edilir.
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);
}
Şimdi bir havuzun en ilginç kısmı, getList()
yöntem. Yöntem çevirmek zorundadır koleksiyonu yöntem çağrıları içine koşulları.
getList()
SerachCriteria
İşin en zor yanı , özellikle toplama koşullarını ayarlama sözdizimi, bir EAV veya düz bir masa varlığı olup olmadığına bağlı olarak farklı olduğundan, filtreler için doğru koşulları AND
ve OR
koşulları sağlamaktır.
Çoğu durumda, getList()
aşağıdaki örnekte gösterildiği gibi uygulanabilir.
<?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;
}
}
Bir içindeki filtreler FilterGroup
bir OR operatörü kullanılarak birleştirilmelidir .
Ayrı filtre grupları, mantıksal AND operatörü kullanılarak birleştirilir .
Phew
Bu en büyük işti. Diğer arayüz uygulamaları daha basittir.
DTO
Magento ilk olarak, geliştiricileri DTO'yu varlık modelinden farklı olarak ayrı sınıflar olarak uygulama niyetindeydi.
Çekirdek takımı sadece olsa müşteri modülü (için yaptım \Magento\Customer\Api\Data\CustomerInterface
tarafından uygulanmaktadır \Magento\Customer\Model\Data\Customer
değil \Magento\Customer\Model\Customer
).
Diğer tüm durumlarda varlık modeli DTO arayüzünü uygular (örneğin \Magento\Catalog\Api\Data\ProductInterface
tarafından uygulanır \Magento\Catalog\Model\Product
).
Konferanstaki çekirdek ekibin üyelerine bu konuyu sordum, ancak iyi uygulama olarak kabul edilmesi gereken net bir yanıt alamadım.
Benim izlenimim bu tavsiyenin terk edilmiş olduğudur. Bu konuda resmi bir açıklama almak iyi olurdu.
Şimdilik, modeli DTO arayüz uygulaması olarak kullanmak için pratik bir karar verdim. Ayrı bir veri modeli kullanmanın daha temiz olduğunu düşünüyorsanız, bunu yapmaktan çekinmeyin. Her iki yaklaşım da pratikte iyi çalışır.
DTO etkileşimi uzatırsa Magento\Framework\Api\ExtensibleDataInterface
, modelin uzatılması gerekir Magento\Framework\Model\AbstractExtensibleModel
.
Genişletilebilirliği umursamıyorsanız, model ORM model temel sınıfını genişletmeye devam edebilir Magento\Framework\Model\AbstractModel
.
Örnek HamburgerInterface
genişlediğinden, ExtensibleDataInterface
hamburger modeli AbstractExtensibleModel
burada görüldüğü gibi, genişler :
<?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);
}
}
Özellik adlarını sabitlere ayıklamak, onları bir yerde tutmaya izin verir. Alıcı / ayarlayıcı çifti tarafından ve ayrıca veritabanı tablosunu oluşturan Setup komut dosyası tarafından kullanılabilirler. Aksi halde, bunları sabitlere çıkarmakta fayda yoktur.
SearchResult
Bu SearchResultsInterface
, uygulanacak üç arayüzün en basitidir, çünkü bütün işlevselliklerini bir çerçeve sınıfından miras alabilir.
<?php
namespace VinaiKopp\Kitchen\Model;
use Magento\Framework\Api\SearchResults;
use VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface;
class HamburgerSearchResult extends SearchResults implements HamburgerSearchResultInterface
{
}
ObjectManager tercihlerini yapılandırma
Uygulamalar tamamlanmasına rağmen, Magento Framework nesne yöneticisi hangi uygulamaları kullanacağını bilmediğinden arayüzleri diğer sınıfların bağımlılıkları olarak kullanamıyoruz. etc/di.xml
Tercihler için bir konfigürasyon eklememiz gerekiyor .
<?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>
Depo bir API kaynağı olarak nasıl gösterilebilir?
Bu kısım gerçekten basittir, ara yüzleri oluşturan tüm çalışmalardan, uygulamalardan ve onları birbirine bağlayanlardan geçmenin ödülü.
Tek yapmamız gereken bir etc/webapi.xml
dosya oluşturmak .
<?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>
Bu konfigürasyonun yalnızca deponun REST bitiş noktaları olarak kullanılmasına izin vermediğini, aynı zamanda SOAP API'sinin bir parçası olarak yöntemleri de ortaya koyduğunu unutmayın.
İlk örnek rotada, <route method="GET" url="/V1/vinaikopp_hamburgers/:id">
yer tutucu :id
, argümanın adını eşlenen yöntemle eşleştirmek zorundadır public function getById($id)
.
İki /V1/vinaikopp_hamburgers/:hamburgerId
argüman eşleşmelidir, örneğin , metot argümanı değişken ismi olduğu için işe yaramaz $id
.
Bu örnek için erişilebilirliği ayarlıyorum <resource ref="anonymous"/>
. Bu, kaynağın herhangi bir kısıtlama olmaksızın kamuya açık olarak kullanıldığı anlamına gelir!
Bir kaynağı yalnızca giriş yapmış bir müşterinin kullanımına açmak için kullanın <resource ref="self"/>
. Bu durumda, me
kaynak bitiş noktası URL'sindeki özel kelime $id
, şu anda oturum açmış olan müşterinin kimliğiyle bir değişken değişkenini doldurmak için kullanılacaktır .
Magento Müşterisine bir göz atın etc/webapi.xml
ve CustomerRepositoryInterface
ihtiyacınız olursa.
Son olarak, <resources>
bir kaynağa yönetici kullanıcı hesabına erişimi kısıtlamak için de kullanılabilir. Bunu yapmak için <resource>
ref'ı bir etc/acl.xml
dosyada tanımlanan bir tanımlayıcıya ayarlayın .
Örneğin, <resource ref="Magento_Customer::manage"/>
müşterileri yönetmek için ayrıcalıklı olan herhangi bir yönetici hesabına erişimi kısıtlar.
Curl kullanarak örnek bir API sorgusu şöyle görünebilir:
$ curl -X GET http://example.com/rest/V1/vinaikopp_hamburgers/123
Not: Bu bir cevap olarak başladı yazılı https://github.com/astorm/pestle/issues/195
göz atın Havaneli , satın Commercebug ve haline patreon @alanstorm arasında