Lima Teknik Teruji-Pertempuran yang Tidak Digunakan Pengembang API WordPress Anda

Diterbitkan: 2022-03-11

Salah satu cara terbaik untuk meningkatkan status Anda sebagai pengembang WordPress, setidaknya di mata klien Anda, adalah menjadi ahli dalam menggunakan API. Berikut skenario umum untuk implementasi WordPress API: Klien Anda meminta Anda untuk menambahkan widget ke situs mereka—misalnya, widget langganan email. Anda mengambil beberapa kode dari layanan email pihak ketiga—mungkin itu tag skrip atau iframe —tempelkan ke halaman, dan balas klien Anda, “Mengerti!”

Sayangnya, Anda berurusan dengan klien yang agak lebih menuntut dan mereka melihat ketidaksempurnaan berikut:

  • Meskipun widget, seperti situs lainnya, menampilkan font sans-serif, itu tidak sepenuhnya benar. Widget menggunakan Helvetica alih-alih font khusus yang telah Anda instal.
  • Formulir berlangganan widget memicu pemuatan halaman baru, yang dapat mengganggu jika ditempatkan di tengah-tengah artikel.
  • Widget tampaknya membutuhkan waktu ekstra untuk memuat setelah sisa halaman, yang terasa menggelegar dan murah.
  • Klien ingin pelanggan ditandai dengan metadata berdasarkan pos tempat mereka berlangganan, dan widget tidak menawarkan apa pun yang mirip dengan fungsi ini.
  • Klien merasa terganggu karena mereka sekarang harus mengelola dua dasbor (wp-admin dan area admin untuk layanan email).

Pada titik ini, satu dari dua hal mungkin saja terjadi. Anda dapat menyatakan item ini "bagus untuk dimiliki" dan meyakinkan klien Anda tentang manfaat dari solusi 80/20, atau Anda dapat memenuhi permintaan tersebut. Dalam pengalaman pribadi saya, saya telah menemukan bahwa memberikan permintaan seperti itu—yaitu, menunjukkan penguasaan layanan pihak ketiga—adalah cara yang andal untuk meyakinkan klien bahwa Anda adalah semacam penyihir WordPress. Plus, sering kali menyenangkan untuk dilakukan.

Selama dekade terakhir, saya telah menggunakan WordPress sebagai platform untuk konsumsi API terhadap kemungkinan 50 API yang berbeda. Beberapa API yang paling umum adalah MailChimp, Google Analytics, Google Maps, CloudFlare, dan Bitbucket. Tetapi bagaimana jika Anda perlu berbuat lebih banyak, bagaimana jika Anda membutuhkan solusi khusus?

Cara Mengembangkan Klien API WordPress

Dalam artikel ini, saya akan mengembangkan API "layanan email" generik, mencoba yang terbaik untuk menjaga segala sesuatunya se-agnostik mungkin. Namun, saya merasa masuk akal untuk berasumsi bahwa kita berurusan dengan JSON REST API. Berikut adalah beberapa topik latar belakang yang mungkin membantu Anda menikmati poin teknis dalam artikel ini:

  • Keluarga fungsi WordPress HTTP
  • JSON
  • ISTIRAHAT

Jika Anda menemukan diri Anda sedikit akrab dengan topik ini dan tertarik untuk menggali lebih dalam, jeda sekarang dan unduh aplikasi Postman yang luar biasa. Ini memungkinkan Anda untuk berkomunikasi dengan API tanpa menulis kode.

Tangkapan layar dasbor Postman

Tukang pos. Mungkin alat pengembangan favorit saya?

Namun, jika Anda sama sekali tidak terbiasa dengan itu, tetaplah membaca. Audiens teknis dengan beberapa tingkat pengalaman WordPress akan mendapatkan hasil maksimal dari artikel ini, tetapi saya akan berhati-hati untuk menjelaskan nilai setiap teknik dengan cara yang kurang teknis. Pembaca non-teknis akan membiarkan artikel ini dapat menilai ROI setiap poin sebelum mensponsori dan menilai kualitas implementasi setelah disampaikan.

Catatan: Jika Anda memerlukan kursus penyegaran cepat, Anda dapat melihat panduan API REST WordPress kami.

Tanpa basa-basi lagi, izinkan saya untuk berbagi dengan Anda beberapa teknik berbeda yang saya hargai di sebagian besar setiap API, proyek, dan tim tempat saya bekerja.

Transien: Kapan Memegangnya, Kapan Melipatnya

Dalam paragraf pembuka saya, saya mencatat bahwa klien merasa menjengkelkan untuk mengangkangi dua area admin: wp-admin dan dasbor untuk layanan email mereka. Cara yang baik untuk menyelesaikannya adalah dengan memberi mereka widget dasbor di wp-admin, untuk menampilkan ringkasan aktivitas pelanggan terbaru mereka.

Tangkapan layar widget dasbor wp-admin

Contoh jenis UI dasbor yang mungkin kami sediakan di WordPress, untuk menghemat perjalanan klien kami ke penyedia layanan email pihak ketiga mereka.

Tetapi sekali lagi, ini mungkin memerlukan beberapa permintaan HTTP ke API jarak jauh (API yang disediakan oleh layanan email), yang mengakibatkan pemuatan halaman yang panjang. Solusi untuk masalah kinerja ini adalah dengan menyimpan panggilan API sebagai transien. Artikel Codex ini memberikan penjelasan yang bagus yang harus Anda baca, tetapi saya akan meringkasnya sebagai berikut:

  1. Dapatkan data dari API jarak jauh.
  2. Simpan menggunakan set_transient() dengan waktu kedaluwarsa yang Anda pilih berdasarkan penilaian Anda sendiri tentang kinerja, batas kecepatan, dan margin kesalahan dalam menampilkan data usang dalam aplikasi khusus ini.
  3. Lanjutkan logika bisnis Anda—memproses data, mengembalikan nilai, apa pun masalahnya.
  4. Saat Anda membutuhkan data lagi, seperti pada pemuatan halaman berikutnya, periksa di cache sementara menggunakan get_transient() sebelum menyimpulkan bahwa Anda perlu mendapatkannya dari API.

Saya menganggap ini sebagai fondasi yang bermanfaat dan layak, tetapi Anda dapat mengambil langkah lebih jauh jika Anda berpikir sejenak tentang kata kerja REST. Dari lima metode yang paling umum (GET, POST, PATCH, PUT, DELETE), hanya satu yang termasuk dalam cache sementara Anda. Bisakah Anda menebak yang mana? Ini GET. Di plugin saya, saya hampir selalu memiliki kelas PHP yang didedikasikan untuk mengabstraksi panggilan ke API jarak jauh yang dimaksud, dan argumen saat membuat instance kelas itu adalah metode HTTP. Jika ini bukan panggilan GET, maka saya tidak akan memanggil lapisan caching sama sekali.

Selanjutnya, jika ini bukan panggilan GET, maka masuk akal bahwa saya mengambil beberapa tindakan untuk mengubah data jarak jauh dalam beberapa cara, mungkin dengan menambahkan, mengedit, atau menghapus pelanggan email. Ini mungkin saat yang tepat untuk membatalkan cache yang ada untuk sumber daya itu, melalui delete_transient() .

Untuk kembali ke contoh kami tentang API langganan email WordPress, berikut cara kerjanya dalam praktik:

  • Widget dasbor untuk menampilkan pelanggan terbaru akan memanggil titik akhir API untuk /subscribers melalui permintaan GET. Karena ini adalah permintaan GET, itu disimpan di cache sementara saya.
  • Widget bilah sisi untuk berlangganan daftar email akan memanggil titik akhir API untuk /subscribers melalui permintaan POST. Karena ini adalah permintaan POST, tidak hanya akan menghindari cache sementara saya, itu akan memprovokasi saya untuk menghapus bagian yang relevan dari cache sementara saya, sehingga widget dasbor mencerminkan pelanggan baru ini.
  • Saat menamai transien, saya sering mengaturnya dengan menamainya secara harfiah setelah URL API jarak jauh yang saya panggil. Ini adalah cara praktis untuk mengidentifikasi transien yang benar untuk dihapus. Jika ini adalah titik akhir yang membutuhkan argumen, saya akan menggabungkannya menjadi string dan menambahkannya ke nama sementara juga.

Sebagai klien atau pemangku kepentingan lain yang kurang teknis, Anda harus secara khusus meminta cache sementara—atau setidaknya diskusi tentangnya—setiap kali aplikasi menarik data dari layanan jarak jauh. Anda harus membiasakan diri dengan plugin Query Monitor yang sangat baik untuk mendapatkan pandangan tentang cara kerja transien. Ini akan memberi Anda antarmuka untuk menjelajahi data apa yang disimpan sebagai sementara, seberapa sering, dan untuk berapa lama.

Terkadang Transien Tidak Cukup Baik

Beberapa layanan hosting WordPress premium sebenarnya tidak mengizinkan Anda menggunakan transien dalam produksi. Mereka menjalankan kode, mungkin dalam bentuk plugin MU atau skrip lain, yang akan mencegat upaya Anda untuk menggunakan API transien dan menyimpan informasi itu melalui cache objek. WP-Engine, dalam konfigurasi yang paling umum, adalah contoh utama dari ini.

Tangkapan layar tampilan phpMyAdmin dijelaskan dalam keterangan

Pemandangan yang mengkhawatirkan di UI phpMyAdmin: Situs produksi yang sama sekali tidak memiliki transien? Ini kemungkinan berarti caching objek sedang bekerja.

Jika Anda hanya menyimpan dan mengambil data, Anda sebenarnya tidak perlu mempedulikan hal ini dan bahkan mungkin tidak pernah menyadarinya. Seluruh rangkaian fungsi *_transient() akan memberi Anda hasil akhir yang sama, hanya difilter untuk menggunakan cache objek alih-alih cache sementara. Namun, di mana Anda mungkin mengalami masalah, adalah saat mencoba menghapus transien. Inilah alasannya.

Jika integrasi API Anda cukup kompleks untuk mendapatkan laman setelannya sendiri, Anda mungkin ingin menyertakan UI agar pengguna admin dapat mengosongkan seluruh cache sementara untuk plugin Anda . Penggunaan paling umum untuk tombol ini adalah ketika klien mengubah beberapa data secara langsung di layanan jarak jauh, dan ingin membatalkan cache yang kami simpan di WordPress. Tombol ini mungkin juga berguna jika klien mengubah kredensial akun, kunci API, atau hanya secara umum sebagai tombol "reset pabrik" untuk debugging.

Tangkapan layar tombol opsi

Contoh UI untuk mengizinkan klien mengosongkan cache lokal untuk data API mereka.

Bahkan jika Anda cukup pintar untuk memberi nama semua kunci sementara Anda sehingga Anda memiliki harapan untuk mengidentifikasi masing-masing untuk delete_transient() , skenario kasus terbaik mungkin masih melibatkan SQL mentah, yang selalu saya coba hindari di WordPress:

 <?php // Purge all the transients associated with our plugin. function purge() { global $wpdb; $prefix = esc_sql( $this -> get_transient_prefix() ); $options = $wpdb -> options; $t = esc_sql( "_transient_timeout_$prefix%" ); $sql = $wpdb -> prepare ( " SELECT option_name FROM $options WHERE option_name LIKE '%s' ", $t ); $transients = $wpdb -> get_col( $sql ); // For each transient... foreach( $transients as $transient ) { // Strip away the WordPress prefix in order to arrive at the transient key. $key = str_replace( '_transient_timeout_', '', $transient ); // Now that we have the key, use WordPress core to the delete the transient. delete_transient( $key ); } } ?>

Tidak nyaman, tidak efisien. Alih-alih, situasi ini memerlukan caching objek karena caching objek memberi kita cara mudah untuk mengelompokkan nilai-nilai yang di-cache bersama -sama . Dengan cara ini, ketika Anda perlu mengosongkan semua nilai yang di-cache terkait dengan plugin Anda, itu adalah panggilan satu baris sederhana ke wp_cache_delete( $key, $group ) .

Saya akan meringkas semua ini dengan mengatakan: Anda tidak bisa menjadi ahli dalam menggunakan API jika Anda belum ahli dalam mengelola cache untuk data itu.

Sebagai klien, hal utama yang harus diperhatikan adalah perilaku cache yang menyimpang antara lingkungan staging dan produksi. Dengan kata lain, meskipun menguji batch pekerjaan baru dalam staging selalu merupakan praktik yang baik, caching adalah sesuatu yang juga harus diuji dalam produksi dengan hati-hati.

API Jarak Jauh Dapat Membantu Menginformasikan Hirarki Kelas PHP Anda

Saat meletakkan berbagai kelas PHP untuk plugin saya, saya sering merasa terbantu untuk meniru cara titik akhir API didefinisikan—misalnya, apa kesamaan titik akhir berikut?

  • https://api.example-email-service.com/v1/subscribers.json
  • https://api.example-email-service.com/v1/lists.json
  • https://api.example-email-service.com/v1/campaigns.json

Mereka semua mengembalikan collections , yang saya maksud adalah hasil dari permintaan GET, mengembalikan hasil nol-ke-banyak di mana setiap hasil adalah anggota array. Itu mungkin terdengar cukup jelas, tetapi saya merasa ini adalah prompt yang membantu untuk struktur kelas berikut dalam kode PHP saya:

  • class.collection.php , kelas abstrak
  • class.subscribers.php memperluas kelas abstrak, Collection .
  • class.lists.php memperluas kelas abstrak, Collection .
  • class.campaigns.php memperluas kelas abstrak, Collection .

Kelas abstrak akan mengambil argumen satu-satunya array parameter kueri: hal-hal seperti pagination, kolom sortir, urutan sortir, dan filter pencarian. Itu akan memiliki metode untuk tugas-tugas umum seperti memanggil API jarak jauh, menangani kesalahan, dan mungkin mengubah hasil menjadi menu HTML <select> atau jQueryUI AutoSuggest. Kelas yang membuat instance kelas abstrak mungkin cukup pendek, mungkin tidak lebih dari sekadar menentukan string untuk digunakan di URL titik akhir API *.json .

Tangkapan layar taman bermain API Mailchimp

Mailchimp menerbitkan "taman bermain" API untuk panggilan API sandboxing dan semacamnya. Ini juga bertindak sebagai cara yang nyaman untuk menjelajahi seluruh hierarki data API mereka, memberi kita gambaran sekilas tentang bagaimana kita dapat menyusun hierarki kelas kita sendiri.

Demikian pula, apa kesamaan titik akhir berikut?

  • https://api.example-email-service.com/v1/subscribers/104abyh4.json
  • https://api.example-email-service.com/v1/lists/837dy1h2.json
  • https://api.example-email-service.com/v1/campaigns/9i8udr43.json

Mereka semua mengembalikan item , yang saya maksud dengan tepat satu anggota koleksi yang spesifik dan unik: hal-hal seperti satu pelanggan email tertentu, satu daftar email, atau satu kampanye email. Oleh karena itu, saya suka menggunakan struktur berikut dalam kode PHP saya:

  • class.item.php , kelas abstrak
  • class.subscriber.php memperluas kelas abstrak, Item .
  • class.list.php memperluas kelas abstrak, Item .
  • class.campaign.php memperluas kelas abstrak, Item .

Kelas abstrak akan mengambil satu-satunya argumen sebagai string untuk mengidentifikasi item spesifik yang diminta. Sekali lagi, kelas yang dipakai mungkin cukup singkat, mungkin tidak lebih dari sekadar menentukan string untuk digunakan di */duy736td.json .

Ada banyak pendekatan untuk menyusun pewarisan kelas, tetapi bahkan jika Anda mengambil pendekatan yang berbeda dengan apa yang telah saya uraikan di atas, saya yakin ada kemungkinan besar bahwa struktur API jarak jauh dapat membantu menginformasikan struktur aplikasi Anda.

Sebagai klien, gejala umum dari arsitektur yang buruk adalah ketika Anda mendapati diri Anda harus meminta perubahan yang sama berulang kali di seluruh aplikasi. Misalnya, jika Anda meminta agar laporan mengembalikan 100 hasil per halaman, bukan 10, dan Anda harus terus mengulangi permintaan itu untuk laporan pelanggan, laporan kampanye, laporan berhenti berlangganan, dll, Anda mungkin mendeteksi arsitektur kelas yang buruk. Dalam situasi ini, ada baiknya bertanya kepada tim Anda apakah mereka akan mendapat manfaat dari siklus refactoring: Sebuah badan kerja di mana tujuannya bukan untuk mengubah perilaku produk melainkan untuk meningkatkan kode yang mendasarinya sehingga menjadi lebih mudah untuk mengubah perilaku. dari produk di masa depan.

Kasus Penggunaan Sempurna untuk WP_Error

Saya malu untuk mengakui bahwa saya membutuhkan waktu bertahun-tahun lebih lama dari yang seharusnya untuk mulai menggunakan keluarga fungsi WP_Error dengan benar dalam kode saya. Saya cenderung hanya mengkodekan jalan saya, baik dengan asumsi tidak akan pernah ada kesalahan yang perlu diperhatikan secara terprogram atau menanganinya berdasarkan kasus per kasus. Bekerja dengan API jarak jauh memotong mentalitas itu seperti sinar laser, karena menyajikan kasus penggunaan yang sangat nyaman dan kuat untuk menggunakan WP_Error .

Ingat sebelumnya bahwa saya sebutkan saya sering memiliki kelas PHP yang tujuannya adalah untuk membuat permintaan HTTP ke API jarak jauh. Ketika Anda mengupas kembali semua boilerplate, semua manipulasi data, semua kekhawatiran sekunder, kelas itu benar-benar turun ke pemanggilan wp_remote_request() untuk mendapatkan objek respons HTTP dari API. Dengan mudah, wp_remote_request() malah akan mengembalikan WP_Error jika panggilan gagal dijalankan karena alasan tertentu, tetapi bagaimana jika panggilan berhasil mengembalikan respons HTTP dari jenis yang tidak menguntungkan?

Tangkapan layar formulir berlangganan

Secara teknis, panggilan API berfungsi , tetapi tidak sepenuhnya bebas dari peringatan. Peringatan ini perlu ditangkap dan dilaporkan secara konsisten di seluruh basis kode.

Sebagai contoh, mungkin kita membuat panggilan ke titik akhir /lists.json , tetapi akun khusus ini belum memiliki daftar yang disiapkan. Ini akan mengembalikan respons HTTP yang valid, tetapi dengan kode status 400. Meskipun itu bukan kesalahan fatal, dari perspektif beberapa kode front-end yang ingin mengubah panggilan API ini menjadi menu tarik-turun, 400 mungkin juga menjadi WSOD! Oleh karena itu, saya merasa terbantu untuk melakukan penguraian tambahan pada hasil wp_remote_request() , yang berpotensi mengembalikan WP_Error :

 <?php function call() { $response = wp_remote_request( $this -> url, $this -> args ); $code = wp_remote_retrieve_response_code( $response ); $first_digit = $code[0]; $good_responses = array( 2, 3 ); if( ! in_array( $first_digit, $good_responses ) { $body = wp_remote_retrieve_body( $response ); $out = new WP_Error( $code, $body ); } else { $out = $response; } return $out; } ?>

Pola ini dapat membantu menyederhanakan kode yang memanggil kelas pemanggil kita, karena kita tahu bahwa kita dapat dengan aman mengandalkan is_wp_error() sebelum melanjutkan dengan output kita.

Sebagai klien, Anda terkadang harus memainkan peran sebagai pengguna jahat, pengguna yang bingung, dan pengguna yang tidak sabar. Gunakan aplikasi dengan cara yang tidak dimaksudkan untuk digunakan. Lakukan hal-hal yang tampaknya tidak diinginkan oleh pengembang Anda. Perhatikan apa yang terjadi. Apakah Anda mendapatkan pesan kesalahan yang bermanfaat? Apakah Anda mendapatkan pesan kesalahan sama sekali? Jika tidak, mungkin ada baiknya mensponsori badan kerja di sekitar penanganan kesalahan yang lebih baik.

Kekuatan Debugging yang Indah dari ob_get_clean()

Web modern yang dapat diprogram, di mana hampir setiap situs menggunakan API dari situs lain, dan digunakan sendiri melalui API-nya sendiri, telah menjadi arena yang sangat kuat untuk kode. Tapi justru kualitas inilah yang juga bisa membuatnya cukup lambat.

Permintaan HTTP jarak jauh adalah hal yang umum untuk menjadi bagian yang paling memakan waktu dari pemuatan halaman tertentu. Untuk alasan ini, banyak komponen yang digerakkan oleh API dijalankan baik melalui Ajax atau cron. Misalnya, saran otomatis untuk mencari melalui daftar pelanggan email mungkin harus melakukan ping ke sumber data jarak jauh sesuai permintaan, pada setiap penekanan tombol, daripada memuat 100.000 pelanggan dalam DOM saat halaman dimuat. Jika itu bukan opsi, mungkin kueri besar dapat disinkronkan pada tugas cron malam, sehingga hasilnya dapat diambil dari mirror lokal daripada API jarak jauh.

Masalah dengan pendekatan ini adalah sulit untuk di-debug. Alih-alih hanya menyalakan WP_DEBUG dan membiarkan pesan kesalahan masuk ke jendela browser Anda, Anda terjebak mencari di konsol jaringan browser, atau mengikuti file log saat tugas cron (semoga?) sedang dijalankan. Saya merasa ini tidak nyaman.

Salah satu cara untuk memperbaiki situasi ini adalah dengan melakukan panggilan yang hati-hati dan strategis ke error_log() . Tapi sekali lagi, masalah umum dengan logging adalah bahwa dengan aplikasi besar atau sibuk, log kesalahan bisa tumbuh terlalu besar, atau tumbuh terlalu cepat, berguna untuk pemantauan atau parsing. Oleh karena itu, kita harus selektif dengan apa yang kita log, menaruh banyak pemikiran ke dalamnya, seperti yang kita lakukan dengan logika aplikasi kita yang sebenarnya . Sangat disayangkan telah meluangkan waktu untuk mencatat beberapa kesalahan kasus tepi eksotis yang tampaknya hanya terjadi sebentar-sebentar pada beberapa tugas cron yang jarang hanya untuk menyadari bahwa sifat sebenarnya dari bug telah menghindari Anda sekali lagi karena Anda gagal mencatat beberapa anggota array tertentu , katakanlah, dari nilai yang menyinggung.

Oleh karena itu, filosofi saya menjadi, saya tidak selalu mencatat, tetapi ketika saya melakukannya, saya mencatat semuanya . Dengan kata lain, setelah mengidentifikasi fungsi yang sangat mengkhawatirkan, saya akan mencatatnya dengan jaring selebar mungkin:

 <?php function debug( $bug ) { ob_start(); var_dump( $bug ); $out = ob_get_clean(); error_log( $out ); } ?>

Ini sama dengan var_dump() 'ing seluruh nilai kereta ke dalam satu entri dalam file log kesalahan.

Tangkapan layar dari file log kesalahan

Log kesalahan yang telah tumbuh terlalu besar untuk menjadi ergonomis untuk debugging.

Sebagai klien, ada baiknya memeriksa secara berkala total penggunaan memori file untuk aplikasi Anda. Jika Anda menyadari bahwa Anda tiba-tiba menabrak batas penyimpanan di akun hosting Anda, ada kemungkinan besar kesalahan log menjadi liar yang harus disalahkan. Pengembang Anda akan mendapat manfaat dari siklus kerja yang berfokus pada pencatatan yang lebih baik—dan pelanggan Anda juga akan mendapat manfaat!

Tidak Persis Clickbait, Tapi Itu Akan Dilakukan

Mohon maafkan struktur daftar artikel ini. Saya tidak dapat memaksakan poin-poin ini menjadi tema artikel yang lebih menyatukan karena pola-pola ini sangat umum: Mereka berlaku untuk titik akhir JSON REST dan keluaran WordPress apa pun .

Itu adalah pola yang saya lihat terjadi berulang kali, terlepas dari apa itu API jarak jauh, atau untuk apa kami menggunakannya di dalam WordPress. Saya telah mengumpulkan semua jenis prinsip ini ke dalam boilerplate plugin yang sangat mempercepat pekerjaan saya. Apakah Anda memiliki poin serupa yang Anda pertahankan untuk setiap proyek? Tolong bagikan agar saya bisa mencurinya dan menambahkannya ke boilerplate saya!

Terkait: Cara Mendekati Pengembangan WordPress Modern (Bagian 1)