Menggunakan SOAP-to-REST untuk Menyederhanakan Migrasi dan Integrasi
Jinhua Luo
March 31, 2023
1. Apa Itu Web Service?
Web service didefinisikan oleh World Wide Web Consortium (W3C) sebagai sistem perangkat lunak yang dirancang untuk mendukung interaksi mesin-ke-mesin yang dapat dioperasikan melalui jaringan.
Web service melakukan tugas tertentu atau serangkaian tugas dan dijelaskan oleh representasi XML standar dari layanan yang disebut Web Services Description Language (WSDL). Deskripsi layanan ini memberikan semua detail yang diperlukan untuk berinteraksi dengan layanan, termasuk format pesan (digunakan untuk menjelaskan operasi secara detail), protokol transport, dan lokasi.
Sistem lain akan berinteraksi dengan web service menggunakan pesan SOAP, biasanya dengan menggunakan HTTP bersama dengan serialisasi XML dan standar web terkait lainnya.
Diagram arsitektur web service (perhatikan bahwa service broker bersifat opsional) adalah:

*Sumber gambar (dilisensikan di bawah CC 3.0 BY-SA): https://en.wikipedia.org/wiki/Web_service
Antarmuka WSDL menyembunyikan informasi detail tentang bagaimana layanan diimplementasikan sehingga penggunaan layanan ini independen dari platform perangkat keras atau perangkat lunak yang mengimplementasikan layanan, serta bahasa pemrograman yang digunakan untuk menulis layanan.
Aplikasi berbasis web service bersifat loosely coupled, berorientasi komponen, dan implementasi lintas teknologi. Web service dapat digunakan secara individu atau bersama dengan web service lain untuk melakukan agregasi kompleks atau transaksi bisnis.
Web service adalah unit implementasi dari Service-oriented architecture (SOA), metode desain yang digunakan untuk menggantikan sistem monolitik. Sistem yang luas dapat dipecah menjadi beberapa web service, yang kemudian dapat digabungkan menjadi kotak hitam besar untuk menyediakan logika bisnis secara eksternal. Mikroservis berbasis kontainer yang populer adalah pengganti terbaru dari web service. Namun, banyak sistem warisan yang sudah berbasis web service untuk implementasi dan operasi, sehingga kompatibilitas dengan sistem ini tetap menjadi tantangan meskipun teknologi berkembang dengan cepat.
WSDL (Web Services Description Language)
WSDL adalah notasi XML yang digunakan untuk mendeskripsikan web service. Definisi WSDL menginstruksikan klien tentang cara menulis permintaan web service dan mendefinisikan antarmuka yang disediakan oleh penyedia web service.
Definisi WSDL dibagi menjadi beberapa bagian, yang menentukan antarmuka logis web service dan detail fisik. Detail fisik mencakup informasi endpoint, seperti nomor port HTTP, serta informasi binding yang menentukan bagaimana merepresentasikan konten pesan SOAP dan metode transport yang digunakan.

Sumber gambar (dilisensikan di bawah CC 3.0 BY-SA): https://en.wikipedia.org/wiki/Web_Services_Description_Language
- File WSDL dapat berisi beberapa layanan.
- Layanan dapat berisi beberapa port.
- Port mendefinisikan alamat URL (yang dapat bervariasi untuk setiap port) dan dapat berisi beberapa operasi.
- Setiap operasi mencakup tipe input dan tipe output.
- Tipe mendefinisikan struktur pesan, termasuk bidang mana yang menyusun pesan, tipe data setiap bidang (yang dapat bersarang), dan jumlah bidang yang diizinkan.
1.1 Apa Itu SOAP
SOAP adalah format pesan XML yang digunakan dalam interaksi web service. Pesan SOAP biasanya dikirim melalui HTTP atau JMS, tetapi protokol transport lain juga dapat digunakan. Definisi WSDL menjelaskan penggunaan SOAP dalam web service tertentu.
Ada dua versi SOAP yang umum digunakan: SOAP 1.1 dan SOAP 1.2.

Sumber gambar (dilisensikan di bawah CC 3.0 BY-SA): https://en.wikipedia.org/wiki/SOAP
Pesan SOAP terdiri dari bagian-bagian berikut:
- Metadata header, yang biasanya kosong
- Body
- Tipe pesan yang didefinisikan dalam WSDL
- Selain respons yang berhasil, ada juga pesan kesalahan terstruktur untuk tipe respons.
Contoh:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header></SOAP-ENV:Header> <SOAP-ENV:Body> <ns2:getCountryResponse xmlns:ns2="http://spring.io/guides/gs-producing-web-service"> <ns2:country> <ns2:name>Spain</ns2:name> <ns2:population>46704314</ns2:population> <ns2:capital>Madrid</ns2:capital> <ns2:currency>EUR</ns2:currency> </ns2:country> </ns2:getCountryResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
1.2 Apa Itu REST
Web service adalah konsep abstrak yang dapat diimplementasikan dengan cara apa pun; misalnya, REST adalah metode implementasi yang populer.
REST, singkatan dari Representational State Transfer, secara harfiah berarti transfer status lapisan presentasi. Roy Thomas Fielding mengusulkan istilah REST dalam disertasi doktoralnya pada tahun 2000. Saat itu, internet sedang booming, dan ada kebutuhan akan definisi praktis untuk pengembangan perangkat lunak dan interaksi dengan jaringan.
Untuk waktu yang lama, penelitian perangkat lunak terutama berfokus pada klasifikasi desain perangkat lunak dan evolusi metode desain. Jarang ada evaluasi objektif tentang dampak pilihan desain yang berbeda terhadap perilaku sistem. Di sisi lain, penelitian jaringan terutama berfokus pada detail perilaku komunikasi antara sistem dan bagaimana meningkatkan kinerja mekanisme komunikasi tertentu, sering kali mengabaikan bahwa mengubah gaya interaksi aplikasi memiliki dampak yang lebih besar pada kinerja keseluruhan daripada mengubah protokol interaksi. Artikel saya bertujuan untuk memahami dan mengevaluasi desain arsitektur perangkat lunak berbasis jaringan yang fungsional, berkinerja baik, dan cocok untuk komunikasi sambil mematuhi prinsip arsitektur.
Mengakses situs web mewakili proses interaksi antara klien dan server. Selama proses ini, pasti ada perubahan data dan status. Protokol HTTP bersifat stateless, artinya semua status disimpan di sisi server. Oleh karena itu, jika klien ingin mengoperasikan server, ia harus menggunakan beberapa cara untuk menyebabkan "transfer status" di sisi server. Karena transfer ini dibangun di atas lapisan presentasi, disebut "transfer status lapisan presentasi."
Empat prinsip dasar REST adalah:
- Gunakan kata kerja HTTP: GET, POST, PUT, DELETE;
- Koneksi stateless, server tidak boleh menyimpan terlalu banyak status kontekstual; artinya, setiap permintaan bersifat independen;
- Tetapkan URI untuk setiap sumber daya;
- Gunakan
x-www-form-urlencodedatau JSON sebagai format data;
Mengonversi SOAP ke REST dapat memudahkan pengguna untuk mengakses web service tradisional dengan cara RESTful, mengurangi biaya pengembangan klien SOAP. Selain itu, jika dapat secara dinamis menyesuaikan diri dengan web service apa pun tanpa pengembangan kode, itu akan lebih sempurna.
Keuntungan terbesar REST adalah tidak memiliki skema, sehingga memudahkan pengembangan, dan JSON memiliki keterbacaan yang lebih tinggi dan redundansi yang lebih rendah.
2. Implementasi Tradisional Proxy SOAP-to-REST
2.1 Konversi Template Manual
Pendekatan ini memerlukan penyediaan template konversi untuk permintaan dan respons untuk setiap operasi web service, yang juga digunakan oleh banyak produk gateway lainnya.
Kita dapat menggunakan plugin APISIX body transformer untuk membuat proxy SOAP-to-REST sederhana dan mencoba pendekatan ini.
Misalnya, kita membuat template permintaan berformat XML untuk operasi getCountry dari CountriesPortService dalam file WSDL berdasarkan definisi tipe.
Di sini, kita mengisi bidang name dalam JSON ke dalam bidang name di getCountryRequest.
req_template=$(cat <<EOF | awk '{gsub(/"/,"\\\"");};1' | awk '{$1=$1};1' | tr -d '\r\n' <?xml version="1.0"?> <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"> <soap-env:Body> <ns0:getCountryRequest xmlns:ns0="http://spring.io/guides/gs-producing-web-service"> <ns0:name>{{_escape_xml(name)}}</ns0:name> </ns0:getCountryRequest> </soap-env:Body> </soap-env:Envelope> EOF )
Template XML-to-JSON perlu disediakan untuk respons, yang bisa sedikit lebih kompleks (terutama jika perbedaan versi SOAP perlu dipertimbangkan). Ini karena perlu ditentukan apakah respons berhasil:
- Untuk respons yang berhasil, bidang dapat langsung dipetakan ke JSON.
- Untuk respons yang gagal (yaitu fault), struktur JSON terpisah diperlukan, dan harus ditentukan apakah bidang opsional tertentu ada.
rsp_template=$(cat <<EOF | awk '{gsub(/"/,"\\\"");};1' | awk '{$1=$1};1' | tr -d '\r\n' {% if Envelope.Body.Fault == nil then %} { "currency":"{{Envelope.Body.getCountryResponse.country.currency}}", "population":{{Envelope.Body.getCountryResponse.country.population}}, "capital":"{{Envelope.Body.getCountryResponse.country.capital}}", "name":"{{Envelope.Body.getCountryResponse.country.name}}" } {% else %} { "message":{*_escape_json(Envelope.Body.Fault.faultstring[1])*}, "code":"{{Envelope.Body.Fault.faultcode}}" {% if Envelope.Body.Fault.faultactor ~= nil then %} , "actor":"{{Envelope.Body.Fault.faultactor}}" {% end %} } {% end %} EOF )
Konfigurasikan routing APISIX dan lakukan pengujian:
curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H 'X-API-KEY: xxx' -X PUT -d ' { "methods": ["POST"], "uri": "/ws/getCountry", "plugins": { "body-transformer": { "request": { "template": "'"$req_template"'" }, "response": { "template": "'"$rsp_template"'" } } }, "upstream": { "type": "roundrobin", "nodes": { "localhost:8080": 1 } } }' curl -s http://127.0.0.1:9080/ws/getCountry \ -H 'content-type: application/json' \ -X POST -d '{"name": "Spain"}' | jq { "currency": "EUR", "population": 46704314, "capital": "Madrid", "name": "Spain" } # Respons fault { "message": "Your name is required.", "code": "SOAP-ENV:Server" }
Seperti yang kita lihat, metode ini memerlukan pemahaman manual tentang definisi setiap operasi dalam file WSDL dan alamat web service yang sesuai dengan setiap operasi. Jika file WSDL besar, berisi banyak operasi, dan memiliki definisi tipe yang kompleks, maka pendekatan ini bisa sangat merepotkan, sulit untuk di-debug, dan rentan terhadap kesalahan.
2.2 Apache Camel
Camel adalah framework integrasi Java terkenal yang digunakan untuk mengimplementasikan pipa routing yang mengonversi protokol dan logika bisnis yang berbeda, dan SOAP-to-REST hanyalah salah satu kasus penggunaannya.
Menggunakan Camel memerlukan pengunduhan dan impor file WSDL, menghasilkan kode stub untuk klien SOAP, dan menulis kode Java:
- Mendefinisikan endpoint REST
- Mendefinisikan rute konversi protokol, seperti bagaimana bidang JSON dipetakan ke bidang SOAP
Sebagai contoh, mari kita pertimbangkan web service untuk konversi unit suhu:
https://apps.learnwebservices.com/services/tempconverter?wsdl
- Hasilkan kode klien SOAP berdasarkan file WSDL menggunakan Maven.
cxf-codegen-plugin akan menghasilkan endpoint klien SOAP untuk kita mengakses web service.
<build> <plugins> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <configuration> <wsdlOptions> <wsdlOption> <wsdl>src/main/resources/TempConverter.wsdl</wsdl> </wsdlOption> </wsdlOptions> </configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
- Menulis bean klien SOAP.
Perhatikan bahwa kita mengingat nama bean sebagai cxfConvertTemp, yang akan digunakan saat mendefinisikan rute Camel nanti.
import com.learnwebservices.services.tempconverter.TempConverterEndpoint; @Configuration public class CxfBeans { @Value("${endpoint.wsdl}") private String SOAP_URL; @Bean(name = "cxfConvertTemp") public CxfEndpoint buildCxfEndpoint() { CxfEndpoint cxf = new CxfEndpoint(); cxf.setAddress(SOAP_URL); cxf.setServiceClass(TempConverterEndpoint.class); return cxf; } }
- Tulis rute REST downstream terlebih dahulu.
Dari rute ini, kita dapat melihat bahwa ia mendefinisikan URL gaya RESTFul dan definisi parameternya, serta mendefinisikan rute hop berikutnya untuk setiap URL. Misalnya, /convert/celsius/to/fahrenheit/{num} mengambil bagian terakhir URL sebagai parameter (tipe double) dan menyediakannya ke rute hop berikutnya direct:celsius-to-fahrenheit.
rest("/convert") .get("/celsius/to/fahrenheit/{num}") .consumes("text/plain").produces("text/plain") .description("Convert a temperature in Celsius to Fahrenheit") .param().name("num").type(RestParamType.path).description("Temperature in Celsius").dataType("int").endParam() .to("direct:celsius-to-fahrenheit");
- Terakhir, tulis rute SOAP upstream dan transformasi antara upstream dan downstream.
from("direct:celsius-to-fahrenheit") .removeHeaders("CamelHttp*") .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { // Inisialisasi permintaan SOAP // Isi parameter downstream num ke dalam body, yang merupakan tipe double sederhana. CelsiusToFahrenheitRequest c = new CelsiusToFahrenheitRequest(); c.setTemperatureInCelsius(Double.valueOf(exchange.getIn().getHeader("num").toString())); exchange.getIn().setBody(c); } }) // Tentukan operasi SOAP dan namespace // Didefinisikan dalam file application.properties .setHeader(CxfConstants.OPERATION_NAME, constant("{{endpoint.operation.celsius.to.fahrenheit}}")) .setHeader(CxfConstants.OPERATION_NAMESPACE, constant("{{endpoint.namespace}}")) // Kirim paket menggunakan bean klien SOAP yang dihasilkan oleh WSDL. .to("cxf:bean:cxfConvertTemp") .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { // Tangani respons SOAP // Isi body, yang merupakan nilai tipe double, ke dalam string // Kembalikan string ke downstream MessageContentsList response = (MessageContentsList) exchange.getIn().getBody(); CelsiusToFahrenheitResponse r = (CelsiusToFahrenheitResponse) response.get(0); exchange.getIn().setBody("Temp in Farenheit: " + r.getTemperatureInFahrenheit()); } }) .to("mock:output");
- Uji
curl localhost:9090/convert/celsius/to/fahrenheit/50 Temp in Farenheit: 122.0
Seperti yang kita lihat, menggunakan Camel untuk SOAP-to-REST memerlukan definisi rute dan logika konversi untuk semua operasi menggunakan kode Java, yang memerlukan biaya pengembangan.
Demikian pula, jika WSDL berisi banyak layanan dan operasi, menggunakan Camel untuk proxying juga bisa merepotkan.
2.3 Kesimpulan
Mari kita rangkum kelemahan metode tradisional.
| Modul | Camel | |
|---|---|---|
| WSDL | parsing manual | pembuatan kode melalui Maven |
| upstream | parsing manual | konversi otomatis |
| definisikan body | sediakan template untuk penilaian dan konversi | tulis kode konversi |
| dapatkan parameter | variabel Nginx | definisikan dalam kode atau panggil antarmuka klien SOAP untuk mendapatkan |
Kedua pendekatan ini memiliki biaya pengembangan, dan untuk setiap web service baru, biaya pengembangan ini perlu diulang.
Biaya pengembangan sebanding dengan kompleksitas web service.
3. Proxy SOAP-to-REST APISIX
Pendekatan proxy tradisional memerlukan penyediaan template konversi atau penulisan kode konversi, keduanya memerlukan pengguna untuk menganalisis file WSDL secara mendalam dan menimbulkan biaya pengembangan yang signifikan.
APISIX menyediakan pendekatan otomatis yang secara otomatis menganalisis file WSDL dan menyediakan logika konversi untuk setiap operasi, menghilangkan biaya pengembangan bagi pengguna.
Ini adalah plugin Enterprise, hubungi kami untuk informasi lebih lanjut.

3.1 Konversi Otomatis Tanpa Kode
Menggunakan proxy SOAP APISIX:
- Tidak diperlukan parsing atau impor manual file WSDL
- Tidak perlu mendefinisikan template konversi
- Tidak perlu menulis kode konversi atau penggabungan apa pun.
Pengguna hanya perlu mengonfigurasi URL WSDL, dan APISIX akan secara otomatis melakukan konversi. Ini cocok untuk web service apa pun, adalah program generik, dan tidak memerlukan pengembangan ulang untuk kebutuhan spesifik.
3.2 Konfigurasi Dinamis
- URL WSDL dapat diikat ke rute apa pun dan, seperti objek sumber daya APISIX lainnya, dapat diperbarui saat runtime. Perubahan konfigurasi berlaku secara dinamis tanpa perlu memulai ulang APISIX.
- URL layanan yang terkandung dalam file WSDL (yang mungkin memiliki beberapa URL), yaitu alamat upstream, akan secara otomatis dikenali dan digunakan sebagai upstream SOAP tanpa perlu pengguna melakukan parsing dan konfigurasi.
3.3 Mekanisme Implementasi
- Dapatkan konten file WSDL dari URL WSDL dan secara otomatis menghasilkan objek proxy setelah analisis.
- Objek proxy bertanggung jawab untuk konversi protokol:
- Hasilkan permintaan XML SOAP yang sesuai berdasarkan input JSON.
- Konversi respons XML SOAP ke respons JSON.
- Akses web service dan tangani detail protokol SOAP secara otomatis, seperti respons tipe fault.
- Dukung SOAP1.1 dan SOAP1.2 serta beberapa fitur ekstensi, seperti WS-Addressing.
3.4 Contoh Konfigurasi
Penjelasan parameter konfigurasi untuk plugin SOAP:
| Parameter | Diperlukan? | Deskripsi |
|---|---|---|
wsdl_url | Ya | URL WSDL, misalnya, https://apps.learnwebservices.com/services/tempconverter?wsdl |
Uji:
# Konfigurasikan routing APISIX menggunakan plugin SOAP # Perhatikan bahwa satu rute dapat mengeksekusi semua operasi, dengan nama operasi ditentukan menggunakan parameter URL # Ini juga mencerminkan manfaat dari proxy dinamis, menghilangkan kebutuhan untuk analisis manual setiap operasi dalam file WSDL. curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H 'X-API-KEY: xxx' -X PUT -d ' { "methods": ["POST"], "uri": "/getCountry", "plugins": { "soap": { "wsdl_url": "http://localhost:8080/ws/countries.wsdl" } } }' curl 'http://127.0.0.1:9080/getCountry' \ -X POST -d '{"name": "Spain"}' # Panggilan berhasil HTTP/1.1 200 OK Date: Tue, 06 Dec 2022 08:07:48 GMT Content-Type: text/plain; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Server: APISIX/2.99.0 {"currency":"EUR","population":46704314,"capital":"Madrid","name":"Spain"} # Panggilan gagal HTTP/1.1 502 Bad Gateway Date: Tue, 03 Jan 2023 13:43:33 GMT Content-Type: text/plain; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Server: APISIX/2.99.0 {"message":"Your name is required.","actor":null,"code":"SOAP-ENV:Server","subcodes":null,"detail":null}
4. Kesimpulan
Di dunia saat ini, web service telah berkembang hingga titik di mana banyak pengguna perusahaan mengandalkan web service berbasis SOAP tradisional untuk menyediakan layanan mereka. Karena alasan historis dan pertimbangan biaya, layanan ini tidak selalu cocok untuk refactoring lengkap menjadi layanan RESTful. Akibatnya, ada permintaan yang signifikan untuk SOAP-to-REST di antara banyak pengguna perusahaan.
Plugin SOAP-to-REST yang disediakan oleh APISIX dapat mencapai fungsionalitas proxy tanpa kode, dapat dikonfigurasi secara dinamis, dan tidak memerlukan pengembangan ulang, yang bermanfaat untuk migrasi dan integrasi bisnis tanpa biaya bagi pengguna perusahaan.