Pengembangan aplikasi seluler tanpa server

Sangat sering ketika mengembangkan aplikasi mobile (mungkin masalah yang sama dengan aplikasi web), pengembang menemukan diri mereka dalam situasi di mana backend tidak berfungsi atau tidak menyediakan metode yang diperlukan.

Situasi ini dapat terjadi karena berbagai alasan. Namun, paling sering pada awal pengembangan, backend tidak ditulis dan klien memulai tanpanya. Dalam hal ini, awal pengembangan tertunda 2-4 bulan

Terkadang server dimatikan (crash), terkadang tidak punya waktu untuk meluncurkan metode yang diperlukan, kadang-kadang ada masalah data, dll. Semua masalah ini membuat kami menulis layanan Mocker kecil yang memungkinkan Anda mengganti backend yang sebenarnya.



Bagaimana saya bisa sampai pada ini
Bagaimana saya sampai pada ini? Tahun pertama saya di perusahaan berakhir dan mereka menempatkan saya pada proyek e-commerce baru. Manajer mengatakan bahwa proyek perlu diselesaikan dalam 4 bulan, tetapi tim backend (di sisi pelanggan) akan memulai pengembangan hanya setelah 1,5 bulan. Dan selama ini kita harus membuang banyak fitur UI.

Saya menyarankan untuk menulis backend moch (sebelum saya menjadi pengembang iOS, saya bermain dengan .NET di uni). Gagasan implementasi sederhana: menurut spesifikasi yang diberikan, perlu menulis metode rintisan yang akan mengambil data dari file JSON yang sudah disiapkan sebelumnya. Mereka memutuskan itu.

Setelah 2 minggu, saya pergi berlibur dan berpikir: "Mengapa saya tidak secara otomatis menghasilkan semua ini?" Jadi selama 2 minggu liburan saya menulis mirip seorang penerjemah yang mengambil spesifikasi APIBlueprint dan menghasilkan .NET Web App darinya (kode C #).

Sebagai hasilnya, versi pertama dari benda ini muncul dan kami bertahan di sana selama hampir 2,5 bulan. Saya tidak bisa memberikan bilangan real, seberapa banyak ini membantu kami, tetapi saya ingat bagaimana mereka mengatakan dalam retrospeksi bahwa jika itu bukan untuk sistem ini, tidak akan ada rilis.

Sekarang, setelah beberapa tahun, saya memperhitungkan kesalahan yang saya lakukan (dan ada banyak kesalahan) dan sepenuhnya menulis ulang instrumen itu.

Mengambil kesempatan ini - terima kasih banyak kepada kolega yang membantu dengan umpan balik dan saran. Dan juga kepada para pemimpin yang menanggung semua "kesewenang-wenangan rekayasa" saya.

Pendahuluan


Sebagai aturan, setiap aplikasi client-server terlihat seperti ini:



Setiap layar memiliki setidaknya 1 permintaan (dan seringkali lebih). Bergerak jauh ke dalam layar, kita perlu membuat lebih banyak permintaan. Kadang-kadang kita bahkan tidak bisa melakukan transisi sampai server memberi tahu kita "Tampilkan tombol". Artinya, aplikasi seluler sangat terikat dengan server, tidak hanya selama pekerjaan segera, tetapi juga pada tahap pengembangan. Pertimbangkan siklus pengembangan produk abstrak:



  1. Pertama kita mendesain. Kami membusuk, menggambarkan, dan berdiskusi.
  2. Setelah menerima tugas dan persyaratan, kami memulai pengembangan. Kami menulis kode, set huruf, dll.
  3. Setelah kami mengimplementasikan sesuatu, perakitan sedang dipersiapkan, yang masuk ke pengujian manual, di mana aplikasi diperiksa untuk kasus yang berbeda.
  4. Jika semuanya baik-baik saja dengan kami, dan penguji menguji perakitan, ia pergi ke pelanggan yang melakukan penerimaan.

Setiap proses ini sangat penting. Terutama yang terakhir, karena pelanggan harus mengerti pada tahap apa kita sebenarnya, dan kadang-kadang dia perlu melaporkan hasilnya kepada manajemen atau investor. Sebagai aturan, laporan tersebut terjadi, termasuk dalam format demonstrasi aplikasi seluler. Dalam praktik saya, ada kasus ketika seorang pelanggan menunjukkan hanya setengah dari MVP, yang hanya bekerja pada moka. Aplikasi mok terlihat seperti hadiah dan dukun seperti hadiah. Jadi itu nyata (:
Namun, ini adalah mimpi merah muda. Mari kita lihat apa yang sebenarnya terjadi jika kita tidak memiliki server.



  1. Proses pengembangan akan lebih lambat dan lebih menyakitkan, karena kami tidak dapat menulis layanan secara normal, kami juga tidak dapat memeriksa semua kasus, kami harus menulis bertopik yang perlu dihapus nanti.
  2. Setelah kami melakukan kebaktian dengan kesedihan, para penguji yang melihatnya dan tidak mengerti apa yang harus dilakukan dengannya. Anda tidak dapat memeriksa apa pun, setengahnya tidak berfungsi sama sekali, karena tidak ada server. Akibatnya, mereka kehilangan banyak bug: baik logis maupun visual.
  3. Nah, setelah "bagaimana mereka bisa terlihat," Anda perlu memberikan perakitan kepada pelanggan dan kemudian yang paling tidak menyenangkan dimulai. Pelanggan tidak dapat benar-benar mengevaluasi pekerjaan, ia melihat 1-2 kasus dari semua kemungkinan dan tentu saja tidak dapat menunjukkannya kepada investornya.

Secara umum, semuanya akan menurun. Dan sayangnya, situasi seperti itu terjadi hampir selalu: kadang-kadang tidak ada server selama beberapa bulan, kadang-kadang setengah tahun, kadang-kadang hanya dalam proses server sangat terlambat atau Anda perlu dengan cepat memeriksa kasus batas yang dapat direproduksi menggunakan manipulasi data pada server nyata.

Misalnya, kami ingin memeriksa bagaimana aplikasi berperilaku jika pembayaran pengguna lebih lama dari tanggal jatuh tempo. Sangat sulit (dan lama) untuk mereproduksi situasi seperti itu di server dan kita perlu melakukan ini secara buatan.

Karena itu, ada masalah berikut:

  1. Server benar-benar hilang. Karena itu, tidak mungkin untuk merancang, menguji dan menyajikan.
  2. Server tidak punya waktu, yang mengganggu pengembangan dan dapat mengganggu pengujian.
  3. Kami ingin menguji batas kasus, dan server tidak dapat membiarkan ini tanpa gerakan panjang.
  4. Mempengaruhi pengujian dan presentasi yang mengancam.
  5. Server macet (sekali, selama pengembangan stabil, kami kehilangan server selama 3,5 hari).

Untuk mengatasi masalah ini, Mocker diciptakan.

Prinsip kerja


Mocker adalah layanan web kecil yang di-host di suatu tempat, mendengarkan lalu lintas pada port tertentu dan dapat merespons dengan data yang telah disiapkan untuk permintaan jaringan tertentu.

Urutannya adalah sebagai berikut:

1. Klien mengirim permintaan.
2. Mocker menerima permintaan tersebut.
3. Mocker menemukan mocker yang diinginkan.
4. Mocker mengembalikan mock yang diinginkan.

Jika semuanya jelas dengan poin 1,2 dan 4, maka 3 mengajukan pertanyaan.

Untuk memahami bagaimana layanan menemukan tiruan yang diperlukan untuk klien, pertama-tama kita mempertimbangkan struktur tiruan itu sendiri.

Mock adalah file JSON dalam format berikut:

{ "url": "string", "method": "string", "statusCode": "number", "response": "object", "request": "object" } 

Mari kita menganalisis setiap bidang secara terpisah.

url


Parameter ini digunakan untuk menentukan URL permintaan yang diakses klien.

Misalnya, jika aplikasi seluler membuat permintaan ke url host.dom/path/to/endpoint , maka di bidang url kita perlu menulis /path/to/endpoint .
Yaitu, bidang ini menyimpan jalur relatif ke titik akhir .

Bidang ini harus diformat dalam format url-template, yaitu format berikut diizinkan:

  1. /path/to/endpoint - alamat url normal. Ketika permintaan diterima, layanan akan membandingkan garis karakter dengan karakter.
  2. /path/to/endpoint/{number} - url dengan pola path. Mock dengan URL semacam itu akan menanggapi permintaan apa pun yang cocok dengan pola ini.
  3. /path/to/endpoint/data?param={value} - url dengan pola-parameter. Mengejek dengan url seperti itu akan memicu permintaan berisi parameter yang diberikan. Selain itu, jika salah satu parameter tidak ada dalam permintaan, maka tidak akan cocok dengan templat.

Dengan demikian, dengan mengontrol parameter URL, Anda dapat dengan jelas menentukan bahwa tiruan tertentu akan kembali ke url tertentu.

metode


Ini adalah metode http yang diharapkan. Misalnya POST atau GET .
String harus hanya berisi huruf kapital.

statusCode


Ini adalah kode status http untuk respons. Artinya, dengan meminta tiruan ini, klien akan menerima respons dengan status yang tercatat di bidang statusCode.

tanggapan


Bidang ini berisi objek JSON yang akan dikirim ke klien dalam isi respons terhadap permintaannya.

permintaan


Ini adalah badan permintaan yang diharapkan akan diterima dari klien. Ini akan digunakan untuk memberikan tanggapan yang diinginkan tergantung pada badan permintaan permintaan. Misalnya, jika kita ingin mengubah jawaban tergantung pada parameter permintaan.

 { "url": "/auth", "method": "POST", "statusCode": 200, "response": { "token": "cbshbg52rebfzdghj123dsfsfasd" }, "request": { "login": "Tester", "password": "Valid" } } 

 { "url": "/auth", "method": "POST", "statusCode": 400, "response": { "message": "Bad credentials" }, "request": { "login": "Tester", "password": "Invalid" } } 

Jika klien mengirim permintaan dengan badan:

 { "login": "Tester", "password": "Valid" } 

Maka sebagai tanggapan dia akan menerima:

 { "token": "cbshbg52rebfzdghj123dsfsfasd" } 

Dan jika kita ingin memeriksa bagaimana aplikasi akan bekerja jika kata sandi dimasukkan secara tidak benar, maka permintaan akan dikirim dengan badan:

 { "login": "Tester", "password": "Invalid" } 

Maka sebagai tanggapan dia akan menerima:
 { "message": "Bad credentials" } 

Dan kita dapat memeriksa kasingnya dengan kata sandi yang salah. Dan untuk semua kasus lainnya.

Dan sekarang kita akan mencari tahu bagaimana pengelompokan dan mencari kerja moq yang diinginkan.



Untuk mencari mok yang diinginkan dengan cepat dan mudah, server memuat semua mokas ke dalam memori dan mengelompokkannya dengan cara yang benar. Gambar di atas menunjukkan contoh pengelompokan.

Server menggabungkan moka berbeda dengan url dan metode . Ini perlu, antara lain, agar kita dapat membuat banyak mok berbeda di satu url.

Sebagai contoh, kami ingin tarik-ke-Refresh yang terus-menerus menarik, jawaban yang berbeda datang dan keadaan layar berubah setiap saat (untuk memeriksa semua kasus batas).

Kemudian kita dapat membuat banyak moks yang berbeda dengan metode dan parameter url yang sama, dan server akan mengembalikannya kepada kita secara iteratif (pada gilirannya).
Sebagai contoh, mari kita memiliki moka seperti:

 { "url": "/products", "method": "GET", "statusCode": 200, "response": { "name": "product", "currency": 1, "value": 20 } } 

 { "url": "/products", "method": "GET", "statusCode": 200, "response": { "name": "gdshfjshhkfhsdgfhshdjgfhjkshdjkfsfgbjsfgskdf", "currency": 5, "value": 100000000000 } } 

 { "url": "/products", "method": "GET", "statusCode": 200, "response": null } 

 { "url": "/products", "method": "GET", "statusCode": 400, "response": null } 

Kemudian, ketika kita memanggil metode GET / produk untuk pertama kalinya, kita akan mendapatkan jawabannya:

 { "name": "product", "currency": 1, "value": 20 } 

Ketika kami memanggil kedua kalinya, pointer iterator akan bergeser ke elemen berikutnya dan kembali kepada kami:

 { "name": "gdshfjshhkfhsdgfhshdjgfhjkshdjkfsfgbjsfgskdf", "currency": 5, "value": 100000000000 } 

Dan kita dapat memeriksa bagaimana aplikasi berperilaku jika kita mendapatkan nilai besar. Dan sebagainya.

Nah, dan ketika kita sampai ke elemen terakhir dan memanggil metode lagi, elemen pertama akan kembali kepada kita lagi, karena iterator akan kembali ke elemen pertama.

Proxy caching


Mocker dapat bekerja dalam mode proxy caching. Ini berarti bahwa ketika suatu layanan menerima permintaan dari klien, ia mengeluarkan alamat host di mana server sebenarnya berada dan skema (untuk menentukan protokol). Kemudian dibutuhkan permintaan yang diterima (dengan semua tajuknya, jadi jika metode ini memerlukan otentikasi, maka tidak apa-apa, Authorization: Bearer ... Anda Authorization: Bearer ... ditransfer) dan memotong informasi layanan darinya ( host dan scheme ) dan mengirimkan permintaan ke server yang sebenarnya.

Setelah menerima respons dengan kode ke-200, Mocker menyimpan jawaban ke file Mock (ya, Anda kemudian dapat menyalin atau mengubahnya) dan mengembalikan kepada klien apa yang diterima dari server sebenarnya. Selain itu, itu tidak hanya menyimpan file ke tempat acak, tetapi mengatur file sehingga Anda dapat bekerja dengannya secara manual. Misalnya, Mocker mengirimkan permintaan ke URL berikut: hostname.dom/main/products/loans/info . Kemudian akan membuat folder hostname.dom , lalu di dalamnya akan membuat folder main , di dalamnya folder products ...

Untuk menghindari duplikat tiruan, nama dibentuk berdasarkan metode http (GET, PUT ...) dan hash dari badan respons server sebenarnya . Dalam hal ini, jika sudah ada ejekan pada jawaban tertentu, maka itu hanya akan ditimpa.

Fitur ini dapat diaktifkan secara terpisah untuk setiap permintaan. Untuk melakukan ini, tambahkan tiga header ke permintaan:

 X-Mocker-Redirect-Is-On: "true", X-Mocker-Redirect-Host: "hostaname.ex:1234", X-Mocker-Redirect-Scheme: "http" 

Indikasi eksplisit dari jalan ke mock


Terkadang Anda ingin Mocker mengembalikan hanya mokas yang kita inginkan, dan tidak semua yang ada di proyek.

Terutama relevan untuk penguji. Akan lebih mudah bagi mereka untuk memiliki semacam set moka yang disiapkan untuk masing-masing kasus uji. Dan kemudian, selama pengujian, QA hanya memilih folder yang dibutuhkan dan berfungsi dengan tenang, karena tidak ada lagi suara dari mengejek pihak ketiga.

Sekarang ini mungkin. Untuk mengaktifkan fungsi ini, Anda perlu menggunakan header khusus:

 X-Mocker-Specific-Path: path 

Sebagai contoh, biarkan Mocker memiliki struktur folder seperti itu di root

 root/ block_card_test_case/ mocks.... main_test_case/ blocked_test_case/ mocks... 

Jika Anda perlu menjalankan test case tentang kartu yang diblokir, maka
X-Mocker-Specific-Path: block_card_test_case
Jika Anda perlu menjalankan test case yang terkait dengan mengunci layar utama, maka
X-Mocker-Specific-Path: main_test_case/blocked_test_case

Antarmuka


Pada awalnya, kami bekerja dengan mokas secara langsung melalui ssh, tetapi dengan peningkatan jumlah mokas dan pengguna, kami beralih ke opsi yang lebih nyaman. Sekarang kami menggunakan CloudCommander.
Dalam contoh komposisi buruh pelabuhan, ia berikatan dengan wadah Mocker.

Itu terlihat seperti ini:



Nah, bonusnya adalah web-editor, yang memungkinkan Anda untuk menambah / mengubah moki langsung dari browser.



Ini juga solusi sementara. Dalam rencana untuk menjauh dari bekerja dengan moks melalui sistem file ke beberapa database. Dan karenanya, akan dimungkinkan untuk mengendalikan mokas sendiri dari GUI ke DB ini.

Penempatan


Cara termudah untuk menggunakan Mocker adalah menggunakan Docker. Selain itu, penggelaran layanan dari buruh pelabuhan akan secara otomatis menyebarkan antarmuka berbasis web yang dengannya lebih nyaman untuk bekerja dengan moka. File yang dibutuhkan untuk penyebaran melalui Docker ada di dalam repositori.

Namun, jika opsi ini tidak cocok untuk Anda, Anda dapat secara mandiri mengumpulkan layanan dari sumbernya. Cukup untuk ini:

 git clone https://github.com/LastSprint/mocker.git cd mocker go build . 

Maka Anda perlu menulis file konfigurasi ( contoh ) dan memulai layanan:

 mocker config.json 

Masalah yang Diketahui


  • Setelah setiap file baru, Anda perlu melakukan curl mockerhost.dom/update_models agar layanan membaca file lagi. Saya tidak menemukan cara cepat dan elegan untuk memperbaruinya
  • Terkadang bug CloudCommander (atau saya melakukan sesuatu yang salah) dan itu tidak memungkinkan pengeditan moki yang dibuat melalui antarmuka web. Itu diperlakukan dengan membersihkan cache browser.
  • Layanan hanya berfungsi dengan application/json . Paket mendukung form-url-encoding .

Ringkasan


Mocker adalah layanan web yang memecahkan masalah pengembangan aplikasi client-server ketika server tidak siap karena beberapa alasan.

Layanan ini memungkinkan Anda untuk membuat banyak tiruan yang berbeda ke satu URL, memungkinkan Anda untuk menghubungkan Permintaan dan Respons satu sama lain dengan secara eksplisit menentukan parameter di url, atau langsung dengan mengatur badan permintaan yang diharapkan. Layanan ini memiliki antarmuka berbasis web yang sangat menyederhanakan kehidupan pengguna.

Setiap pengguna layanan dapat secara mandiri menambahkan titik akhir yang diperlukan dan permintaan yang dibutuhkannya. Dalam hal ini, pada klien, untuk beralih ke server nyata, cukup dengan mengganti konstanta dengan alamat host.

Saya harap artikel ini akan membantu orang yang menderita masalah serupa dan, mungkin, kita akan bekerja sama untuk mengembangkan alat ini.

Repositori GitHub .

Source: https://habr.com/ru/post/id477506/


All Articles