Saya mencoba mengembalikan objek JSON dari salah satu Model REST saya, sesuatu seperti ini:
{
"settings": {
"set1" : 2,
"set2" : "key1"
},
"extra": {
"e1'" : {
"e2'": true
}
}
}
Namun, apa yang tampaknya sepele, tidak mudah diimplementasikan. Masalahnya adalah saya tidak yakin apa yang harus jenis kembali di antarmuka dan model.
<?php
namespace AppFactory\Core\Api;
/**
* @api
*/
interface SettingsInterface
{
/**
* @return object
*/
public function get();
}
Kelas objek akan kembali
{
"message": "Class object does not exist",
saat memanggil API. Tipe primitif, int, angka, dan array yang tersedia tidak akan berfungsi untuk saya. Saya tidak ingin membuat kelas untuk setiap tipe kompleks juga kembali. Bagaimana saya bisa melakukan ini?
Terima kasih.
magento2
webapi
magento2-api
Yehia A.Salam
sumber
sumber
Jawaban:
Saya berasumsi itu
AppFactory\Core\Api\SettingInterface::get()
adalah titik akhir REST. Dalam hal ini dalam komentar phpdoc, Anda perlu menentukan apa yang akan dikembalikan. Handler Magento REST akan mengambil nilai itu dan memprosesnya untuk menghapus semua data yang tidak perlu. Apa yang tersisa akan dikodekan ke dalam JSON sehingga dalam javascript Anda dapat mengambilnya sebagai JS hash yang tepat dan bukan string yang dikodekan json.Trik tentang titik akhir itu adalah bahwa Anda perlu mendefinisikan dengan tepat apa yang akan Anda kembalikan. Magento tidak akan dapat memproses sesuatu yang umum seperti "array" di mana Anda akan mengatur apa pun yang Anda suka.
Dalam kasus Anda, agar tidak mencoba bermain dengan serangkaian string, akan lebih mudah untuk membuat antarmuka yang akan dikembalikan oleh titik akhir Anda.
Sekarang ketika Anda mengembalikan sebuah instance dari objek yang mengimplementasikan antarmuka itu, Magento akan membaca phpdocs-nya dan akan memproses nilai pengembaliannya. Sekarang buat file
AppFactory\Core\Api\Data\SettingsInterface
sebagai berikutSekarang ketika Anda membuat kelas aktual yang akan mengimplementasikan 2 metode get tersebut dan Anda akan mengembalikannya
AppFactory\Core\Api\SettingsInterface::get()
lalu magento akan mengembalikan sesuatu sepertiJika Anda ingin level lain, Anda perlu membuat antarmuka lain yang akan mempertahankan
settings
struktur dan menambahkannya sebagai nilai balik untukAppFactory\Core\Api\Data\SettingsInterface::getSettings()
.Jika Anda perlu memiliki sesuatu yang dinamis dan Anda tidak ingin atau tidak dapat mempersiapkan antarmuka struktur ini maka Anda dapat mencoba mengatur string json-encoded dan menempatkan
@return string
untuk salah satu bidang. Namun demikian, Anda harus memastikan untuk mendekode string secara manual setelah menerima respons, sehingga respons Anda akan terlihat seperti ini:dan untuk menggunakan
response.extra.test
Anda harus terlebih dahulu melakukannyaresponse.extra = JSON.parse(response.extra);
secara manualsumber
AppFactory\Core\Api\DataSettingsInterface
. Jika ini berhasil, Anda hanya perlu melakukan respons tingkat pertama.Saya juga menghadapi masalah ini, dan sebagai alternatif untuk solusi yang diusulkan oleh Zefiryn, saya telah mengatasinya dengan melampirkan data yang dikembalikan dalam sebuah array (atau dua). Silakan perhatikan contoh di bawah ini.
Karena cara Magento 2 memungkinkan array konten campuran sebagai nilai pengembalian, struktur data yang lebih kompleks dapat disematkan di dalam array lainnya. Sampel di atas menghasilkan respons JSON berikut (terpotong agar mudah dibaca).
Menutupnya dalam satu lapisan menghapus kunci-kunci array, dan tanpa melampirkannya dalam array apa pun menghasilkan kesalahan.
Dapat dimengerti tidak ada dari ini yang ideal, tetapi pendekatan ini memungkinkan saya untuk mengontrol konsistensi dalam struktur data yang dikembalikan ke tingkat tertentu (struktur dan jenis data yang diharapkan). Jika Anda juga mengendalikan penulisan perpustakaan sisi klien, pencegat dapat diimplementasikan untuk menghapus array luar sebelum mengembalikannya ke aplikasi.
sumber
Untuk Magento 2.3.1, jika Anda perlu memotong serialisasi array, Anda dapat memeriksa file ini untuk memperbarui logika inti. Saya pikir ini adalah titik masuk yang baik. Tetapi dengan melakukan ini Anda pasti akan merusak kompatibilitas Sabun.
Selain itu di Magento 2.1.X, Anda tidak memiliki masalah ini jika Anda memasukkan anyType sebagai tipe pengembalian.
Referensi Github: https://github.com/magento/magento2/blob/2.3-develop/lib/internal/Magento/Framework/Reflection/TypeCaster.php
Referensi perubahan komit: https://github.com/magento/magento2/commit/6ba399cdaea5babb373a35e88131a8cbd041b0de#diff-53855cf24455a74e11a998ac1a871bb8
vendor / magento / framework / Reflection / TypeCaster.php: 42
Dan ganti dengan:
sumber
Saya tahu pertanyaan ini sudah cukup lama, tetapi ada satu solusi yang cukup sederhana untuk ini:
Anda harus mengganti Json-Renderer
Magento\Framework\Webapi\Rest\Response\Renderer\Json
atau menulis Plugin untuknya.Berikut sedikit contoh plugin:
Di Anda
di.xml
Di Kelas Plugin baru Anda
Namespace\Module\Plugin\Webapi\RestResponse\JsonPlugin
Apa yang terjadi di sini:
Tentu saja Anda juga dapat menulis Renderer Anda sendiri, yang memproses array misalnya.
sumber
Saya menghadapi masalah yang sama dan butuh beberapa saat untuk mencari tahu masalahnya.
Magento melakukan sesuatu yang aneh di sana, web prosesor layanan output api yang terletak di bawah Magento \ Framework \ Webapi \ ServiceOutputProcessor Di kelas ini ada metode bernama convertValue (); yang merupakan alasan untuk kawat gigi [].
Solusi terbaik bagi saya untuk menyelesaikan masalah adalah membuat plugin sekitar untuk mengatasi kondisi ini jika di convertValue (); metode di mana mereka memeriksa apakah $ data adalah sebuah array dan melakukan hal-hal aneh dengannya.
Berikut ini contoh kode plugin saya: Saya pikir setiap orang tahu cara membuat modul Magento 2 dasar, jadi saya hanya memposting kode plugin itu sendiri di sini.
Buat folder Plugin
Buat kelas Vendor \ ModuleName \ Plugin \ ServiceOutputProcessorPlugin.php
Ini harus menyelesaikan masalah output json array di api web
Semoga ini membantu
sumber