আমি @ryanF- এর দুর্দান্ত উত্তরের পাশাপাশি কিছুটা বিশদ দিতে চাই।
আমি কাস্টম সত্তাগুলির জন্য একটি সংগ্রহস্থল যুক্ত করার কারণগুলি সংক্ষিপ্ত করতে চাই, কীভাবে এটি করা যায় তার উদাহরণ দেই এবং ওয়েব এপিআইয়ের অংশ হিসাবে কীভাবে সেই সংগ্রহস্থলগুলি প্রকাশ করতে হবে তাও ব্যাখ্যা করব।
দাবি অস্বীকার: আমি কেবল তৃতীয় পক্ষের মডিউলগুলির জন্য এটি কীভাবে করা যায় তার একটি বাস্তববাদী পদ্ধতির বর্ণনা দিচ্ছি - মূল দলগুলির নিজস্ব মান রয়েছে যা তারা অনুসরণ করে (বা না)।
সাধারণভাবে, একটি সংগ্রহস্থলের উদ্দেশ্য হ'ল স্টোরেজ সম্পর্কিত যুক্তি লুকানো।
রিপোজিটরির ক্লায়েন্টের যত্ন নেওয়া উচিত নয় যে রিটার্ন করা সত্তা কোনও অ্যারেতে মেমরিতে রাখা আছে, কোনও মাইএসকিউএল ডাটাবেস থেকে রিমোট করা হয়েছে, একটি রিমোট API বা কোনও ফাইল থেকে নেওয়া হয়েছে।
আমি ধরে নিলাম যে ম্যাগেন্টো কোর দলটি এটি করেছে যাতে তারা ভবিষ্যতে ওআরএম পরিবর্তন বা প্রতিস্থাপন করতে সক্ষম হয়। ম্যাজেন্টোতে ওআরএম বর্তমানে মডেলস, রিসোর্স মডেল এবং সংগ্রহগুলি নিয়ে গঠিত।
যদি কোনও তৃতীয় পক্ষের মডিউল কেবল সংগ্রহস্থলগুলি ব্যবহার করে তবে ম্যাজেন্টো কীভাবে এবং কোথায় ডেটা সংরক্ষণ করা হবে তা পরিবর্তন করতে পারে এবং এই গভীর পরিবর্তনগুলি সত্ত্বেও মডিউলটি কাজ চালিয়ে যাবে।
সংগ্রহস্থল সাধারণত মত পদ্ধতি আছে findById()
, findByName()
, put()
বা remove()
।
Magento এসব সাধারণভাবে বলা হয় getbyId()
, save()
এবং delete()
না, এমন ভান তারা অন্য কিছু করছেন কিন্তু টি ককটেলের ডিবি অপারেশন।
ম্যাজেন্টো 2 সংগ্রহস্থল পদ্ধতিগুলি সহজেই এপিআই সংস্থান হিসাবে প্রকাশিত হতে পারে, এগুলি তৃতীয় পক্ষের সিস্টেমগুলি বা শিরোনামহীন ম্যাজেন্টো দৃষ্টান্তগুলির সাথে একীকরণের জন্য মূল্যবান করে তোলে।
"আমি কি আমার কাস্টম সত্তার জন্য একটি সংগ্রহস্থল যুক্ত করব?"
সর্বদা হিসাবে, উত্তর হয়
"এটা নির্ভর করে".
একটি দীর্ঘ গল্প সংক্ষিপ্ত করতে, আপনার সত্তাগুলি যদি অন্য মডিউল দ্বারা ব্যবহৃত হয়, তবে হ্যাঁ, আপনি সম্ভবত একটি সংগ্রহস্থল যুক্ত করতে চান।
এখানে আরও একটি বিষয় রয়েছে যা গণনাতে আসে: ম্যাজেন্টো 2 এ, রিপোজিটরিগুলি সহজেই ওয়েব এপিআই হিসাবে প্রকাশিত হতে পারে - এটি রেস্ট এবং এসওএপি - সংস্থানসমূহ।
যদি এটি আপনার কাছে তৃতীয় পক্ষের সিস্টেমের সংহতকরণের জন্য বা শিরোনামহীন ম্যাজেন্টো সেটআপের কারণে আকর্ষণীয় হয়, তবে আবার, হ্যাঁ, আপনি সম্ভবত আপনার সত্তার জন্য একটি সংগ্রহস্থল যুক্ত করতে চান।
আমি কীভাবে আমার কাস্টম সত্তার জন্য একটি সংগ্রহস্থল যুক্ত করব?
ধরে নেওয়া যাক আপনি REST API এর অংশ হিসাবে আপনার সত্তাকে প্রকাশ করতে চান। যদি এটি সত্য না হয়, আপনি ইন্টারফেসগুলি তৈরি করতে আসন্ন অংশটি এড়িয়ে যেতে পারেন এবং সরাসরি নীচে "সংগ্রহস্থল এবং ডেটা মডেল বাস্তবায়ন তৈরি করুন" এ যেতে পারেন।
সংগ্রহস্থল এবং ডেটা মডেল ইন্টারফেস তৈরি করুন
Api/Data/
আপনার মডিউল মধ্যে ফোল্ডার তৈরি করুন । এটি কেবল কনভেনশন, আপনি আলাদা অবস্থান ব্যবহার করতে পারেন তবে আপনার উচিত হবে না।
সংগ্রহস্থলটি Api/
ফোল্ডারে যায় । উপ- Data/
ডিরেক্টরিটি পরবর্তীকালের জন্য।
ইন Api/
, আপনি যে পদ্ধতিগুলি প্রকাশ করতে চান তার সাথে একটি পিএইচপি ইন্টারফেস তৈরি করুন। ম্যাজেন্টো 2 কনভেনশন অনুসারে সমস্ত ইন্টারফেসের নাম প্রত্যয়ের সাথে শেষ হয় Interface
।
উদাহরণস্বরূপ, কোনও Hamburger
সত্তার জন্য, আমি ইন্টারফেসটি তৈরি করব Api/HamburgerRepositoryInterface
।
সংগ্রহস্থল ইন্টারফেস তৈরি করুন
ম্যাজেন্টো 2 সংগ্রহস্থলগুলি মডিউলটির ডোমেন লজিকের অংশ। এর অর্থ, কোনও সংগ্রহস্থল প্রয়োগ করার জন্য কোনও নির্দিষ্ট সেট নেই।
এটি সম্পূর্ণরূপে মডিউলটির উদ্দেশ্যে নির্ভর করে।
তবে, অনুশীলনে সমস্ত সংগ্রহস্থলগুলি বেশ একই রকম। তারা CRUD কার্যকারিতা জন্য মোড়ক হয়।
সর্বাধিক পদ্ধতি আছে getById
, save
, delete
এবং getList
।
আরও কিছু থাকতে পারে, উদাহরণস্বরূপ CustomerRepository
এর একটি পদ্ধতি রয়েছে get
যা ইমেল দ্বারা গ্রাহককে ধরে নিয়ে যায়, যার getById
মাধ্যমে সত্তা আইডি দ্বারা গ্রাহককে পুনরুদ্ধারে ব্যবহার করা হয়।
এখানে হ্যামবার্গার সত্তার জন্য একটি উদাহরণ সংগ্রহস্থল ইন্টারফেস রয়েছে:
<?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);
}
গুরুত্বপূর্ণ! এখানে টাইমসিনস হতে হবে!
এখানে কয়েকটি গোটাচা রয়েছে যেগুলি ভুল হয়ে থাকলে ডিবাগ করা শক্ত hard
- আপনি যদি এটিকে REST এপিআইতে লাগাতে চান তবে পিএইচপি 7 স্কেলার আর্গুমেন্ট প্রকার বা রিটার্নের প্রকারগুলি ব্যবহার করবেন না !
- সমস্ত আর্গুমেন্টের জন্য পিএইচপিডোক টিকা এবং সমস্ত পদ্ধতিতে রিটার্নের ধরণ যুক্ত করুন!
- পিএইচপিডোক ব্লকে পুরোপুরি যোগ্য শ্রেণীর নাম ব্যবহার করুন !
জেএসওএন বা এক্সএমএল থেকে কীভাবে ডেটা রূপান্তর করতে হয় তা নির্ধারণ করার জন্য টীকাগুলিকে ম্যাজেন্টো ফ্রেমওয়ার্ক দ্বারা পার্স করা হয়েছে। শ্রেণি আমদানি (যা use
বিবৃতি) প্রয়োগ করা হয় না!
প্রতিটি পদ্ধতির কোনও যুক্তির ধরণ এবং রিটার্নের ধরণ সহ একটি টীকা থাকতে হবে। এমনকি যদি কোনও পদ্ধতিতে কোনও আর্গুমেন্ট না নেয় এবং কোনও কিছুই না ফেরায়, তবে এটিকে টীকাতে হবে:
/**
* @return void
*/
স্কালে প্রকার ( string
, int
, float
এবং bool
) এ ছাড়া, নির্দিষ্ট করা আর্গুমেন্ট এবং একটি ফিরতি মান হিসাবে উভয় আছে।
নোট করুন যে উপরের উদাহরণে, এমন পদ্ধতিগুলির জন্য টীকাগুলি যা প্রত্যাবর্তন করে এমন বস্তুগুলিকে ইন্টারফেস হিসাবেও নির্দিষ্ট করা হয়।
রিটার্ন টাইপ ইন্টারফেস সবই Api\Data
নেমস্পেস / ডিরেক্টরিতে থাকে।
এটিতে তারা কোনও ব্যবসায়িক যুক্তি রাখেন না তা বোঝাতে এটি হয়। এগুলি কেবল ডেটা ব্যাগ।
আমাদের এই ইন্টারফেসগুলি পরবর্তী তৈরি করতে হবে।
ডিটিও ইন্টারফেস তৈরি করুন
আমি মনে করি ম্যাজেন্টো এই ইন্টারফেসগুলিকে "ডেটা মডেল" বলে, এটি একটি নাম যা আমি পছন্দ করি না।
শ্রেণী এই ধরনের সাধারণত একটি হিসাবে পরিচিত হয় ডেটা স্থানান্তর অবজেক্ট বা DTO ।
এই ডিটিও ক্লাসগুলিতে কেবল তাদের সমস্ত সম্পত্তিগুলির জন্য গেটার এবং সেটটার রয়েছে।
আমি ডিজিটাল মডেলের চেয়ে ডিটিও ব্যবহার করতে পছন্দ করার কারণটি হ'ল ওআরএম ডেটা মডেলগুলি, রিসোর্স মডেলগুলি বা মডেলগুলি দেখার সাথে বিভ্রান্ত করা কম ... অনেকগুলি জিনিস ইতিমধ্যে ম্যাগেন্তোর মডেল।
সংগ্রহস্থলের ক্ষেত্রে প্রযোজ্য পিএইচপি 7 টাইপ সম্পর্কিত একই সীমাবদ্ধতা ডিটিওগুলিতেও প্রযোজ্য।
এছাড়াও, প্রতিটি পদ্ধতিতে সমস্ত আর্গুমেন্ট প্রকার এবং রিটার্নের ধরণ সহ একটি টীকা থাকতে হবে।
<?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);
}
যদি কোনও পদ্ধতি একটি অ্যারে পুনরুদ্ধার করে বা ফেরত দেয় তবে অ্যারেতে থাকা আইটেমের ধরণটি পিএইচপিডোক টীকাতে নির্দিষ্ট করতে হবে, তারপরে একটি খোলার এবং বন্ধ স্কোয়ার বন্ধনীটি অনুসরণ করা উচিত []
।
এটি উভয় স্কেলারের মানগুলির (যেমন int[]
) পাশাপাশি বস্তুগুলির (যেমন IngredientInterface[]
) উভয়ের ক্ষেত্রে সত্য ।
নোট করুন যে আমি Api\Data\IngredientInterface
কোনও পদ্ধতির বস্তুর অ্যারে ফিরিয়ে দেওয়ার পদ্ধতির উদাহরণ হিসাবে ব্যবহার করছি , আমি এই পোস্টে উপাদানগুলির কোডটি শক্তভাবে যুক্ত করব না।
ExtensibleDataInterface?
উপরে উদাহরণস্বরূপ HamburgerInterface
প্রসারিত ExtensibleDataInterface
।
প্রযুক্তিগতভাবে এটি কেবল তখনই প্রয়োজন যখন আপনি চান অন্য মডিউলগুলি আপনার সত্তার সাথে বৈশিষ্ট্য যুক্ত করতে সক্ষম হবে।
যদি তা হয় তবে আপনার আরও একটি গিটার / সেটার জোড়া যুক্ত করতে হবে, ডাকা কনভেনশন অনুসারে getExtensionAttributes()
এবং setExtensionAttributes()
।
এই পদ্ধতির রিটার্ন টাইপের নামকরণ খুব গুরুত্বপূর্ণ!
ম্যাজেন্টো 2 ফ্রেমওয়ার্কটি ইন্টারফেস, বাস্তবায়ন এবং বাস্তবায়নের জন্য কারখানাটি উত্পন্ন করবে যদি আপনি তাদের ঠিক ঠিক নাম দেন। এই যান্ত্রিকগুলির বিশদটি এই পোস্টের বাইরে থাকলেও।
কেবলমাত্র জেনে রাখুন, আপনি যে জিনিসটিকে এক্সটেনসিবল করতে চান তার ইন্টারফেসটি যদি বলা হয় \VinaiKopp\Kitchen\Api\Data\HamburgerInterface
, তবে এক্সটেনশন অ্যাট্রিবিউটস টাইপ করতে হবে \VinaiKopp\Kitchen\Api\Data\HamburgerExtensionInterface
। সুতরাং শব্দটি প্রত্যয়টির Extension
ঠিক আগে, সত্তার নাম অনুসারে be Interface
োকাতে হবে।
আপনি যদি না চান যে আপনার সত্তাটি এক্সটেনসিবল হয়, তবে ডিটিও ইন্টারফেসের জন্য অন্য কোনও ইন্টারফেস প্রসারিত করতে হবে না getExtensionAttributes()
এবং setExtensionAttributes()
পদ্ধতিগুলি বাদ দেওয়া যেতে পারে।
ডিটিও ইন্টারফেস সম্পর্কে আপাতত যথেষ্ট, রিপোজিটরি ইন্টারফেসে ফিরে আসার সময়।
GetList () রিটার্ন টাইপ অনুসন্ধান ফলাফল
সংগ্রহস্থল পদ্ধতিটি 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 বা ফ্ল্যাট টেবিল সত্তার উপর নির্ভর করে আলাদা different
বেশিরভাগ ক্ষেত্রে, 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
থাকা ফিল্টারগুলিকে একটি ওআর অপারেটর ব্যবহার করে একত্রিত করতে হবে ।
লজিক্যাল অ্যান্ড অপারেটর ব্যবহার করে পৃথক ফিল্টার গ্রুপগুলি একত্রিত করা হয় ।
ইসস
এই কাজটি সবচেয়ে বড় বিট ছিল। অন্যান্য ইন্টারফেস বাস্তবায়ন সহজ।
ডিটিও
ম্যাগেন্টো মূলত ডিটিওকে পৃথক শ্রেণি হিসাবে বাস্তবায়নের উদ্দেশ্যে বিকাশকারীদের সত্তা মডেল থেকে পৃথক করে intended
কোর দলের গ্রাহক মডিউল যদিও (জন্য এটা করেছে \Magento\Customer\Api\Data\CustomerInterface
দ্বারা বাস্তবায়িত হয় \Magento\Customer\Model\Data\Customer
না \Magento\Customer\Model\Customer
)।
অন্যান্য সমস্ত ক্ষেত্রে সত্তা মডেলটি ডিটিও ইন্টারফেস প্রয়োগ করে (উদাহরণস্বরূপ \Magento\Catalog\Api\Data\ProductInterface
এটি প্রয়োগ করা হয় \Magento\Catalog\Model\Product
)।
আমি সম্মেলনগুলিতে মূল দলের সদস্যদের সম্পর্কে এ সম্পর্কে জিজ্ঞাসা করেছি, তবে কী ভাল অনুশীলন হিসাবে বিবেচিত হবে তা আমি একটি পরিষ্কার সাড়া পাইনি।
আমার ধারণাটি এই সুপারিশটি পরিত্যাগ করা হয়েছে। যদিও এই সম্পর্কে একটি সরকারী বিবৃতি পেতে ভাল লাগবে।
আপাতত আমি ডিটিও ইন্টারফেস বাস্তবায়ন হিসাবে মডেলটি ব্যবহার করার ব্যবহারিক সিদ্ধান্ত নিয়েছি। আপনি যদি পৃথক ডেটা মডেল ব্যবহার করা পরিষ্কার মনে করেন তবে নির্দ্বিধায় এটি ব্যবহার করুন। উভয় পন্থা অনুশীলনে সূক্ষ্মভাবে কাজ করে।
ডিটিও ইন্টারফেসটি যদি প্রসারিত করে Magento\Framework\Api\ExtensibleDataInterface
তবে মডেলটি প্রসারিত করতে হবে Magento\Framework\Model\AbstractExtensibleModel
।
আপনি যদি এক্সটেনসিবিলিটি সম্পর্কে চিন্তা না করেন তবে মডেলটি কেবল ওআরএম মডেল বেস শ্রেণিটি প্রসারিত করতে পারে 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);
}
}
স্থির হয়ে থাকা সম্পত্তিগুলির নামগুলি এগুলিকে এক জায়গায় রাখার অনুমতি দেয়। এগুলি গেটর / সেটার জুটি এবং সেটআপ স্ক্রিপ্ট দ্বারা ব্যবহার করা যেতে পারে যা ডেটাবেস টেবিল তৈরি করে। অন্যথায় এগুলি স্থির করে নেওয়ার কোনও লাভ নেই।
অনুসন্ধান ফলাফল
SearchResultsInterface
যেহেতু এটি একটি কাঠামো বর্গ থেকে এটা কার্যকারিতা সব উত্তরাধিকারী করতে পারেন তিন ইন্টারফেসগুলি সহজ বাস্তবায়ন হয়।
<?php
namespace VinaiKopp\Kitchen\Model;
use Magento\Framework\Api\SearchResults;
use VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface;
class HamburgerSearchResult extends SearchResults implements HamburgerSearchResultInterface
{
}
অবজেক্টম্যানেজারের পছন্দগুলি কনফিগার করুন
বাস্তবায়নগুলি সম্পূর্ণ হলেও, আমরা এখনও ইন্টারফেসগুলি অন্য শ্রেণীর নির্ভরতা হিসাবে ব্যবহার করতে পারি না, যেহেতু ম্যাজেন্টো ফ্রেমওয়ার্ক অবজেক্ট ম্যানেজার কী প্রয়োগগুলি ব্যবহার করতে পারে তা জানে না। আমাদের 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>
কীভাবে এপিআই রিসোর্স হিসাবে সংগ্রহস্থল উন্মুক্ত করা যায়?
এই অংশটি সত্যিই সহজ, এটি ইন্টারফেস তৈরির সমস্ত কাজ করে, বাস্তবায়ন এবং তাদের একসাথে ওয়্যারিংয়ের জন্য পুরষ্কার।
আমাদের কেবল একটি 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 এর অংশ হিসাবে পদ্ধতিগুলিও প্রকাশ করে oses
প্রথম উদাহরণের রুটে, <route method="GET" url="/V1/vinaikopp_hamburgers/:id">
স্থানধারককে :id
ম্যাপ করা পদ্ধতির সাথে যুক্তির নামের সাথে মিল করতে হবে public function getById($id)
।
দুটি নামের সাথে মিল রাখতে হবে, উদাহরণস্বরূপ কার্যকর /V1/vinaikopp_hamburgers/:hamburgerId
হবে না, কারণ পদ্ধতির যুক্তি ভেরিয়েবলের নাম $id
।
এই উদাহরণের জন্য আমি অ্যাক্সেসযোগ্যতা সেট করেছি <resource ref="anonymous"/>
। এর অর্থ সম্পদটি কোনও বাধা ছাড়াই প্রকাশ্যে প্রকাশিত হয়!
কোনও লগ ইন করা গ্রাহকের জন্য কোনও সংস্থান উপলব্ধ করতে, ব্যবহার করুন <resource ref="self"/>
। me
এক্ষেত্রে রিসোর্স এন্ডপয়েন্টের ইউআরএলটিতে বিশেষ শব্দটি $id
বর্তমানে লগ ইন করা গ্রাহকের আইডি সহ একটি আর্গুমেন্ট ভেরিয়েবল পপ করতে ব্যবহৃত হবে ।
ম্যাজেন্টো গ্রাহক etc/webapi.xml
এবং আপনার CustomerRepositoryInterface
যদি এটির প্রয়োজন হয় তা একবার দেখুন।
শেষ অবধি, <resources>
প্রশাসক ব্যবহারকারীর অ্যাকাউন্টে কোনও সংস্থান ব্যবহারের সীমাবদ্ধ করতেও এটি ব্যবহার করা যেতে পারে। এটি করতে <resource>
একটি etc/acl.xml
ফাইলের মধ্যে সংজ্ঞায়িত একটি সনাক্তকারী রেফ সেট করুন।
উদাহরণস্বরূপ, <resource ref="Magento_Customer::manage"/>
গ্রাহকদের পরিচালনা করার অধিকার প্রাপ্ত কোনও প্রশাসক অ্যাকাউন্টে অ্যাক্সেস সীমাবদ্ধ করবে।
কার্ল ব্যবহার করে একটি উদাহরণ এপিআই ক্যোয়ারী এটির মতো দেখতে পেল:
$ curl -X GET http://example.com/rest/V1/vinaikopp_hamburgers/123
Note: এই একটি উত্তর হিসাবে শুরু লিখিত https://github.com/astorm/pestle/issues/195
পরীক্ষা করে দেখুন মুষল , কিনতে Commercebug এবং পরিণত patreon @alanstorm এর