Memakai Postman untuk Testing Web API

Postman merupakan aplikasi komersial (tapi ada versi gratisnya) untuk merancang API (Application Programming Interface), mendokumentasikan API, memonitor API, dan testing API berbasis web. Tool ini bisa dipakai oleh developer dan tester.

Di tulisan ini saya hanya akan membahas penggunan Postman untuk testing API. Artinya saya hanya akan membahas bagian Collections dan Environment. Testing API bisa dilakukan untuk development, QA, ataupun pentesting. Postman memudahkan banyak hal untuk testing, misalnya kita bisa melakukan otorisasi, bisa menyimpan token, dan bisa kita program menggunakan JavaScript.

Postman memiliki banyak fitur, hanya dua ini saja yang akan dibahas di tulisan ini

Mengenal API

Application programming interface adalah antarmuka untuk menghubungkan satu program (atau komponen program) dengan yang lain. Istilah API tidak hanya untuk aplikasi web, ada API untuk sistem operasi (misalnya POSIX API, Win32 API), untuk grafik (OpenGL API, Metal API), dsb. Dua komponen program apapun bisa memiliki API.

Dalam sebuah aplikasi, baik mobile maupun web, biasanya ada komponen client (aplikasi/browser) dan ada komponen server yang berkomunikasi dengan menggunakan API. API biasanya hanya berurusan dengan data dan aksi saja, dan bagian client yang akan menanyakan atau menampilkan informasi ke user dengan indah.

Postman hanya mendukung API untuk HTTP dengan REST (Representational State Transfer), dan belum mendukung banyak teknologi lain (misalnya gRPC). API ini biasanya dituliskan dalam bentuk dokumentasi/spesifikasi API, supaya kita tahu kita bisa mengirimkan request apa ketika berhubungan dengan satu sistem, dan apa balasannya. Postman mendukung beberapa spesifikasi API standard yang akan di bahas di bagian lain artikel ini.

Lebih jelasnya kita ambil contoh aplikasi cuaca. Pengguna perlu memilih lokasi mana yang ingin ditampilkan cuacanya. Aplikasi bisa meminta lokasi saat ini ke sistem operasi berdasarkan GPS, atau menampilkan pilihan daftar kota, atau menampilkan peta. Data yang dikirim via API ke server hanyalah nama kota atau koordinatnya saja. Server tidak perlu tahu bagaimana interaksinya dengan user.

Sebaliknya, server hanya membalas dengan data saja, misalnya: cerah, 20 derajat celsius, dan aplikasi yang akan menggambar ikon matahari dengan angka 20 di dekatnya. Dalam kebanyakan kasus, kita hanya berhubungan dengan data teks saja. Walau kadang ada juga API yang berhubungan dengan file, misalnya untuk upload profile picture atau document.

API ini ada yang sifatnya terbuka untuk umum dan tidak butuh otorisasi, dan ada yang sifatnya tertutup/rahasia dan butuh otorisasi. Saat ini semakin jarang yang memberikan API publik 100% gratis karena akan membebani server. Biasanya minimal kita perlu registrasi dan memakai API key. Dengan API key, server bisa membatasi atau memblok kalau-kalau ada terlalu banyak request dari key tersebut.

Dengan Postman kita bisa membuat request ke server, dan melihat balasannya. Seperti yang saya sebutkan: kebanyakan interaksinya adalah berhubungan dengan teks saja. Contohnya kita bisa meminta URL di bawah ini dengan Postman. Ini adalah API cuaca yang saat artikel ini ditulis masih gratis dan publik tanpa API key.

https://goweather.herokuapp.com/weather/Bangkok

Request API Cuaca dengan Postman

Swagger dan OpenAPI

Dulu deskripsi API biasanya dituliskan dalam bentuk dokumen yang hanya bisa dibaca manusia, tapi saat ini sudah ada beberapa standard untuk mendokumentasikan API supaya bisa proses oleh program: Swagger 1.0, Swagger 2.0 dan OpenAPI 3.0. Kenapa ada beberapa versi? dulu ada proyek open source Swagger, yang membuat spesifikasi versi 1.0 lalu diperbaiki menjadi 2.0, dan kemudian spesifikasi ini disumbangkan ke Linux Foundation, dikembangkan dan diubah namanya menjadi OpenAPI 3.0.

Proyek Swagger selain membuat dokumen spesifikasi Swagger juga membuat berbagai tool yang memakai spesifikasi Swagger. Saat ini masih banyak proyek dan tool yang hanya mendukung Swagger 1.0/2.0, tapi ada beberapa converter, ada yang online ataupun offline untuk migrasi antar spesifikasi. Misalnya kita bisa memakai api-spec-converter untuk konversi berbagai spesifikasi di command line.

Spesifikasi API ini bisa dituliskan dalam format YAML atau JSON. Spesifikasi ini bisa ditulis tangan (manual) atau digenerate dengan tool. Tool bisa menghasilkan file YAML/JSON dengan cara mengekstrasi komentar dari source code program.

Spesifikasi yang ditulis manual sering kali salah atau tidak valid, tapi hasil ekstraksi program juga tidak selalu benar. Hasil ekstraksi bisa salah jika komentar tidak diupdate. Meski demikian akan jauh lebih mudah mengecek apakah komentar sesuai dengan kode program di bawahnya dibandingkan membandingkan beberapa file yang terpisah.

Swagger vs Postman

Proyek Swagger memiliki banyak tool yang bisa dipakai baik developer ataupun tester. Toolnya ada yang command line dan ada yang berbasis web. Saat ini tidak ada installer Swagger yang mudah diinstall di desktop untuk pemula, tapi ada versi cloudnya. Swagger cocok sekali untuk bekerja dengan spesifikasi Swagger dan OpenAPI.

Sementara Postman selain versi cloud juga punya versi desktop yang bisa diinstall dengan mudah. Versi desktop Postman mudah dihubungkan ke Burp/Zaproxy untuk keperluan pentesting. Postman bisa memakai spesifikasi Swagger/OpenAPI, tapi bisa dipakai untuk membuat request bebas/manual tanpa harus membuat spesifikasi OpenAPI.

Saya menyarankan agar kedua tool ini dipakai sesuai kebutuhan. Untuk developer, berbagai tool Swagger dapat dipakai. Untuk keperluan testing/pentesting Postman akan lebih praktis dan mudah.

Workspace Postman

Workspace digunakan untuk mengelompokkan pekerjaan. Misalnya kita punya banyak client, tiap client bisa masuk satu workspace. Beberapa produk yang berbeda dari satu perusahaan yang tidak saling berhubungan juga bisa masuk workspace terpisah.

Satu workspace tidak bisa mengakses data dari workspace lain, jadi jika ada pekerjaan yang saling berhubungan (misalnya memakai data yang sama), masukkan ke dalam workspace yang sama. Tapi jika kita memilih menaruh sesuatu (collection/environment) di workspace yang salah, maka kita bisa memindahkan objek tersebut ke workspace lain.

Collections dan Environment

Berbagai request API bisa kita masukkan ke dalam sebuah collection, dan semua Collection bisa diakses di bagian Collections. Cara paling mudah membuat sebuah Collection adalah dengan mengimport file yang sudah ada. File ini bisa berupa file Postman, atau format lain (Swagger, GraphQL, OpenAPI, dsb). Selain dengan mengimpor, cara membuat request adalah dengan cara manual. Biasanya ini melibatkan membaca dokumentasi dan membuat requestnya.

Postman memiliki konsep variabel yang bisa muncul di dalam Global, Collection dan Environment. Variabel Global bisa dipakai di semua tempat, Variabel dalam sebuah collection bisa dipakai untuk semua request di dalam collection tersebut.

Untuk beralih dari satu set variabel ke variabel lain yang akan dipakai di banyak request, masukkan ke dalam bagian Environment. Contohnya jika kita punya URL production https://production.compactbyte.com dan UAT https://uat.compactbyte.com.com, maka URL itu bisa dimasukkan ke dua environment berbeda (production dan UAT). Ketika testing Production, tinggal pilih environment production, dan ketika testing bisa memakai environment UAT.

Kita bisa memilih environment mana yang aktif saat ini dengan memilih di bagian Environment. Sangat penting untuk mengecek environment mana yang aktif, karena ini sumber kesalahan umum. Perlu diperhatikan bahwa bisa juga tidak ada environment aktif sama sekali (tidak ada yang dicentang). Postman tidak otomatis memilih environment pertama yang ada, meskipun hanya ada satu environment.

Satu hal yang cukup mengganggu ketika saya memakai Postman adalah: tidak otomatis menyimpan sesuatu. Jadi misalnya saya membuka tab “Environment” mengedit URL, lalu kembali ke bagian Collections, maka nilai URL tidak disimpan. Saya harus kembali lagi ke Environment, lalu menekan Save.

Memakai Variabel/Environment

Variabel bisa dipakai dengan menggunakan syntax: {{namavariabel}} di dalam sebuah string. Jika variable tidak ketemu, maka string akan dipakai apa adanya. Misalnya kita salah memakai /get/{{user}} padahal seharusnya /get{{username}} maka akan terkirim ke server sebagai string /get{{user}} tanpa warning.

Global variabel bisa diakses dari ikon mata

Cara termudah untuk mengetahui apakah environment ada atau tidak. Gunakan fitur autocomplete. Sudah ada built in global juga dari Postman yang bisa dipakai. Jika variable tidak ketemu coba cek:

  • bahwa namanya benar
  • bahwa sudah menekan “Save” setelah membuat variabelnya
  • bahwa sudah memilih dan mengaktifkan environment yang benar
Autocomplete variable

Otorisasi

Seperti saya sebutkan sebelumnya: kebanyakan API sifatnya tidak publik dan butuh otorisasi. Untungnya Postman sudah memiliki support built in terhadap berbagai metode otorisasi yang umum. Metode yang perlu dipakai tentunya sesuai dengan dokumentasi (sesuai yang didukung oleh server penyedia API).

Metode otorisasi yang didukung saat ini

Bagaimana jika metodenya tidak umum? dalam kasus ini kita perlu menulis skrip sendiri. Beberapa penyedia API juga mewajibkan setiap request memiliki signature atau hash, ini perlu ditangani menggunakan script custom.

Scripting untuk Testing

Postman mendukung penggunaan skrip menggunakan JavaScript. Kita bisa memiliki “Pre-Request script” di bagian Collections, yang akan dijalankan untuk semua request di collection tersebut. Kita juga bisa membuat “Pre-Request Script” di masing-masing request. Sesuai namanya, pre request script akan dijalankan sebelum request dikirimkan.

Contoh sederhana yang bisa dilakukan untuk “pre-request script” adalah membuat ID baru di setiap request. Di dalam API online shop kadang diwajibkan agar setiap request memiliki invoice id yang unik, dengan skrip sederhana kita bisa membuat ID yang angkanya selalu menaik. Contoh pemakaian pre-request script yang lebih umum dan lebih kompleks untuk membuat API butuh signature/hash pada API yang membutuhkan ini.

Setelah request dikirimkan dan kita mendapatkan jawaban, kita juga bisa memproses hasilnya dengan skrip di bagian “Test”. Bagian ini berguna untuk menguji apakah hasil sesuai dengan ekspektasi. Misalnya: kita ingin menguji bahwa API seharusnya tidak boleh diakses oleh user guest. Kita bisa membuat test sederhana seperti pada gambar berikut: intinya kita memeriksa bahwa response codenya harus 401.

Contoh Test sederhana

Tentunya selain menguji HTTP status, kita juga bisa memasukkan test apa saja. Data hasil test bisa diparse dan dicek hasilnya apakah sesuai harapan. Skrip di bagian “Test” juga berguna untuk menyimpan hasil API di environment untuk kemudian dipakai lagi di request lain.

Contoh: jika kita ingin menguji API transaksi dan pembatalan transaksi. Setelah melakukan transaksi, server akan mengembalikan sebuah transaction id, jika kita ingin membatalkan transaksi, maka kita perlu mengirimkan transaction id tersebut di request pembatalan. Kita bisa saja mengcopy paste manual hasil request pertama dari server, tapi kita bisa membuat skrip yang mengekstrak transaction id dari server dan menyimpan di environment agar bisa dipakai di request pembatalan.

Trik Scripting

Scripting Postman kadang perlu trik khusus, dan biasanya ini perlu didapatkan dari membaca forumnya. Contoh: Jika kita ingin memiliki fungsi yang sifatnya global per collection dan bisa diakses di semua request di collection tersebut, maka kita tidak bisa sekedar mendeklarasikan fungsinya di bagian Pre-request Collection. Triknya: di bagian Pre-Request Collection set prototype Object dengan nama fungsi yang kita inginkan (jangan menimpa properti yang sudah ada, akan membuat bingung atau error tidak terduga).

//https://community.postman.com/t/global-functions-via-collection-level-folder/5927/12
Object.prototype.encryptStr = function (data) {
   //your code here
}

Dan dari bagian Request, kita bisa memanggil fungsinya dengan:

let obj = {};
obj.encryptStr("str")

Untuk request yang membutuhkan kriptografi, modul CryptoJS sudah tersedia built in. Kriptografi ini dipakai misalnya untuk membuat hash dengan SHA/MD5/dsb, membuat HMAC, mengenkrip dan mendekrip dengan AES.

Biasanya request yang membutuhkan hashing/signature perlu mengakses URL saat ini. Biasanya ini cukup dengan request.url. Tapi di Pre-Request script jika kita memakai variabel, isinya request.url adalah seperti ini di dalam JavaScript:

/path/{{var1}}//{{var2}}

Artinya: nilai variabelnya belum diganti, meskipun ada di dalam environment. Triknya adalah memanggil fungsi untuk menggantikan environment string dengan nilainya:

var url = pm.variables.replaceIn(request.url.toString())

Intinya: kemungkinan Anda akan menemukan sesuatu yang berjalan dengan normal di console JavaScript browser atau di CLI nodejs tapi tidak jalan di Postman. Solusinya yang saya pakai adalah:

  • debug dengan console.log (memastikan bukan salah coding)
  • lihat request di Burp (memastikan requestnya seperti harapan)
  • cari masalahnya di Google/forum (berharap ada yang punya masalah yang sama)
  • membaca dokumentasi (kadang masalahnya tidak dialami orang lain atau tidak diposting di forum karena ternyata sudah jelas jika kita membaca dokumentasinya)

Contoh Request

Agar lebih jelas mengenai hubungan antara otorisasi, variabel dan request, berikut ini contoh sederhana memakai sebuah API. API yang saya pakai adalah dari api.bible yang memungkinkan kita mengakses Alkitab dalam banyak bahasa.

Langkah pertama adalah mendapatkan deskripsi API-nya. Dalam kasus ini, deskripsi API-nya sudah ada dalam format Swagger JSON dan bisa langsung kita import dari link ini. Dalam kasus API lain, kadang kita hanya diberikan file dokumen dan harus kita buat sendiri requestnya satu per satu. Dalam kasus yang lebih parah lagi, kita perlu membaca source codenya untuk mencari tahu API-nya.

Otorisasi menggunakan API Key

Langkah kedua adalah mencari tahu otorisasi yang dibutuhkan. Tertulis dengan jelas di dokumentasinya bahwa bentuk otorisasi adalah dengan API key. Jika kita import file swagger-nya, defaultnya API key ini adalah placeholder dengan teks <API KEY>. Untuk bisa mengakses API-nya kita perlu mendaftar dan akan langsung mendapatkan API key. Tadinya saya mendaftarkan API Podcast untuk contoh di posting ini, tapi formnya panjang, dan meski sudah diisi lama sekali mendapatkan keynya.

Langkah ketiga adalah mengirimkan request. Setelah mendaftar dan mendapatkan API key, saya bisa mengirimkan request, misalnya meminta daftar Alkitab yang ada yang memakai bahasa Indonesia.

Melakukan request sederhana

Langkah berikutnya terserah Anda. Di sini Anda bisa mulai menambahkan test langsung, atau mungkin ingin membuat skrip-skrip dulu untuk memudahkan request berikutnya. Dalam kasus ini, setelah dipelajari lebih lanjut, ternyata kita perlu mengetahui ID sebuah Alkitab untuk request berikutnya. Misalnya kita ingin mencari teks di Alkitab bahasa Thailand, kita perlu mengirim request untuk mendapatkan daftar berbagi versi yang ada di Thailand, lalu mencari dulu ID-nya, lalu menggunakan ID ini pada request berikutnya.

Supaya contohnya agak sedikit lebih rumit, saya ingin mencari ID Alkitab bahasa Inggris. Sudah ada banyak versi yang terbit sejak ratusan tahun yang lalu, dari yang masih memakai bahasa Inggris jadul sampai yang modern. Saya ingin mencari King James Version. Di bagian Test saya bisa menggunakan skrip semacam ini:

var jsonData = pm.response.json();
let bible_id = '';
for (bible of jsonData['data']) {
    if (bible.name.startsWith("King James")) {
        bible_id = bible.id;
        break;
    }
}
console.log("Found ID " + bible_id)
pm.environment.set("bible_id", bible_id)

Inti skripnya adalah: untuk setiap versi Alkitab yang ditemukan (dengan loop for), cek apakah diawali dengan “King James”. Jika ketemu, saya set bible_id dengan id yang ditemukan. Setelah itu saya mengeset environment bible_id dengan id yang ditemukan.

Mengenai Object default (seperti pm.environment), silakan baca dokumentasi scripting Postman websitenya: https://learning.postman.com/docs/writing-scripts/test-scripts/.

Postman tidak punya fitur debugger, tapi kita bisa menambahkan console.log yang akan muncul di bagian Console. Lihat bagian kiri bawah di gambar ini.

Contoh request dan hasil log-nya

Isi environment bible_id saat ini bisa dicek di bagian environment.

Isi environment saat ini

Lalu isinya bisa kita pakai di request lain. Misalnya saya ingin mencari teks di Alkitab versi ini. Saya perlu mengisi teks yang ingin dicari, lalu ID Alkitabnya. Karena sudah memiliki ID, saya masukkan {{bible_id}} dan ini akan digantikan dengan nilai environment saat ini.

Menggunakan environment

Collection Runner

Postman memiliki fitur untuk menggunakan data dari file CSV atau JSON. Misalnya file ini bisa berisi daftar login/password, atau daftar ID produk. Intinya: isi variabel akan diambil dari file ini (header CSV adalah nama variabelnya). Gunakan fitur “Run” (ada tombolnya di kanan) untuk menjalankan seperangkat test menggunakan file data ini.

Contoh Collection Runner

Untuk kasus pentest fitur ini bisa digunakan untuk fuzzing sederhana. Isi file CSV/JSON-nya bisa berupa payload-payload umum yang bisa membuat error (SQL Injection, command Injection, dsb). Untuk keperluan pentesting, Jika API tidak butuh signature/hashing, menggunakan fitur ini kurang praktis, sebaiknya gunakan fuzzer yang ada di dalam Proxy.

Postman + Burp/Zaproxy

Postman bisa dikombinasikan dengan Burp/Zaproxy/Fiddler (atau intercepting proxy lain, selanjutnya saya sebut Burp saja). Kita bisa mengeset Burp sebagai proxy di Postman, sehingga semua request dari Zaproxy bisa dilihat dengan jelas. Ini berguna untuk dua hal: pentesting, dan mendebug request yang salam.

Contoh request salah: jika tidak ada environment tertentu, nilainya akan dikirim apa adanya. Misalnya {{id}} seharusnya diganti dengan nilai id, tapi jika nilainya tidak diset, maka tetap akan dikirim sebagai string "{{id}}". Meneruskan contoh sebelumnya. Misalnya saya salah mengetik bible_id dengan bibleid (tanpa underscore), maka kesalahan ini dengan mudah terlihat di Burp.

Terlihat URL menjadi salah karena nilai environment tidak ditemukan

Ada keterbatasan dalam hal signature/hashing: jika kita mengimplementasikan hashing di Postman, maka fuzzing tidak bisa dilakukan di Burp/Zaproxy. Logikanya: hasil fuzzing tidak bisa dilihat oleh Postman, jadi tidak bisa diupdate signaturenya. Dalam kasus ini gunakan fitur Collection Runner di Postman.

Penutup

Fitur Postman masih ada banyak sekali yang tidak dibahas di sini. Semoga tulisan ini cukup memperkenalkan fitur Postman supaya bisa dieksplorasi lebih lanjut. Pekerjaan para tester akan jauh lebih enak jika sudah diberi spesifikasi OpenAPI atau Collection Postman yang lengkap. Lengkap di sini artinya meliputi skrip dasar untuk hashing, sehingga tester hanya perlu mengklik run saja.

Ternyata di banyak tempat berbagai testing masih dilakukan manual 100% padahal sebagian besar pekerjaan ini bisa diotomasi. Postman hanyalah salah satu dari berbagai tool untuk automated testing. Semoga perkenalan ini bisa membuat banyak tester (baik untuk QA/Pentest) mulai mempertimbangkan automated testing untuk melengkapi manual testing.

Tinggalkan Balasan

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses.