---
title: Permintaan HTTP dari server Multiplay
slug: world-sdk-guide-id/permintaan-http-dari-server-multiplay
docTags: 
createdAt: 2024-09-02T08:34:13.135Z
---

Anda dapat melakukan permintaan HTTP dari server ZEPETO World Multiplay menggunakan modul ZEPETO.Multiplay.HttpService. Integrasikan layanan web eksternal ke dalam operasi logika bisnis Anda, penyimpanan data, analisis statistik, pelacakan kesalahan, dan lainnya.



:::hint{type="danger"}
- Harap pastikan bahwa hanya protokol HTTPS yang digunakan, sementara HTTP hanya didukung di lingkungan pengembangan.
- Permintaan hanya diizinkan pada port 80 dan 443.
- Ukuran maksimum untuk tubuh permintaan dan respons dibatasi hingga 16KB.
- Jaga jumlah permintaan per menit di bawah 500 untuk menghindari potensi pembatasan pada layanan dunia jika terjadi permintaan berlebihan.
- Permintaan akan gagal jika layanan web eksternal tidak merespons dalam waktu 5 detik.
- Pastikan bahwa content-type dalam header respons sesuai dengan nilai yang ditentukan dalam `HttpContentType` enum; jika tidak, permintaan akan gagal.
- Mengingat kemungkinan permintaan web gagal karena berbagai alasan, disarankan untuk melakukan pengkodean secara defensif.
:::



## ZEPETO.Multiplay.HttpService

:::hint{type="info"}
**📘&#x20;**&#x53;ilakan merujuk ke panduan berikut. \[[API ZEPETO.Multiplay.HttpService](https://developer.zepeto.me/docs/multiplay-server/interfaces/ZEPETO_Multiplay_HttpService.HttpService)]
:::



### Metode

| **Metode**                                                                                                              | **Deskripsi**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| HttpService.getAsync(url: string, headers?: HttpHeader): Promise                                                        | Melakukan permintaan HTTP GET secara asinkron.<br />.**\[Parameter]**<br />- url : Alamat web untuk mengirim permintaan.<br />- headers : Header permintaan HTTP. (Opsional)<br /><br />**\[Nilai Kembali]**<br />- Promise\<HttpResponse> : Mengembalikan objek HttpResponse yang berisi informasi tentang respons sebagai Promise                                                                                                                                                                                                                                                                            |
| HttpService.postAsync(url: string, body: HttpBodyType, headers?: HttpHeader): Promise                                   | Melakukan permintaan HTTP POST secara asinkron.<br />.**\[Parameter]**<br />- url : Alamat web untuk mengirim permintaan.<br />- body : Konten tubuh permintaan.<br />- headers : Header permintaan HTTP. (Opsional)<br /><br />**\[Nilai Kembali]**<br />- Promise\<HttpResponse> : Mengembalikan objek HttpResponse yang berisi informasi tentang respons sebagai Promise                                                                                                                                                                                                                                    |
| HttpService.postAsync(url: string, body: HttpBodyType, httpContentType: HttpContentType, headers?: HttpHeader): Promise | Melakukan permintaan HTTP POST secara asinkron.<br />.**\[Parameter]**<br />- url : Alamat web untuk mengirim permintaan.<br />- body : Konten tubuh permintaan.<br />- httpContentType : Menentukan header Content-Type permintaan.<br />- headers : Header permintaan HTTP. (Opsional)<br /><br />**\[Nilai Kembali]**<br />- Promise\<HttpResponse> : Mengembalikan objek HttpResponse yang berisi informasi tentang respons sebagai Promise.<br /><br />Saat menggunakan tanda tangan ini, jika Anda menambahkan 'Content-Type' ke header, itu akan ditimpa oleh apa yang ditentukan dalam httpContentType |

### Deklarasi Lain

| **Deklarasi**   | **Deskripsi**                                                                                                                                                                                                                                                                                                                                                                                                                     |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| HttpContentType | Enumerasi konstanta yang menentukan Content-Type untuk header HTTP.<br /><br />- ApplicationJson : 'application/json'<br />- ApplicationXml : 'application/xml'<br />- ApplicationUrlEncoded : 'application/x-www-form-urlencoded'<br />- TextPlain : 'text/plain'<br />- TextXml : 'text/xml'                                                                                                                                    |
| HttpBodyType    | Tipe untuk konten tubuh permintaan HTTP, yang bisa berupa string atau objek dengan kunci string dan nilai apa pun.                                                                                                                                                                                                                                                                                                                |
| HttpHeader      | Tipe untuk mendefinisikan header permintaan HTTP, di mana nilai properti bisa berupa string atau angka dalam objek.                                                                                                                                                                                                                                                                                                               |
| HttpResponse    | Antarmuka yang mencakup informasi tentang hasil permintaan HTTP dan data respons.<br /><br />- statusCodeHTTP : Sebuah angka yang mewakili kode status dari respons. Biasanya, 200 menunjukkan permintaan yang berhasil.<br />- statusTextHTTP : Sebuah string yang mewakili pesan status dari respons. Biasanya, "OK" menunjukkan permintaan yang berhasil.<br />- response : Sebuah string yang berisi data tubuh respons HTTP. |

:::hint{type="info"}
**📘 Status HTTP**
[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)
:::



## Contoh Kode

### Permintaan GET Dasar

Mari kita buat contoh permintaan GET sederhana menggunakan `HttpService.getAsync`. Ketika klien baru terhubung ke Ruang Multiplay, kita akan mengirim permintaan HTTP ke layanan web eksternal dan mencatat hasilnya.

[restcountries.com](https://restcountries.com/) adalah API terbuka yang menyediakan informasi tentang berbagai negara. Kami akan menggunakan layanan ini untuk mengetahui ibu kota Jepang.

Siapkan Multiplay, lalu buka World.multiplay/index.ts dan tulis skrip server sebagai berikut.

:::hint{type="info"}
**📘&#x20;**&#x53;ilakan merujuk ke panduan berikut. \[[Bermain Ganda](docId\:cVcG580UMg-HWV8qbGM0p)]
:::



```typescript
import { Sandbox, SandboxOptions, SandboxPlayer } from "ZEPETO.Multiplay";
import { HttpService } from "ZEPETO.Multiplay.HttpService";

export default class extends Sandbox {

    onCreate(options: SandboxOptions) { }
    onJoin(client: SandboxPlayer) { this.findCapitalCity() }
    onLeave(client: SandboxPlayer, consented?: boolean) { }

    findCapitalCity() {
        // Buat permintaan ke API restcountries
        HttpService.getAsync("https://restcountries.com/v3.1/name/japan?fields=capital")
            // Penangan untuk Respons HTTP   
            .then((httpResponse) => {
                // Parse data respons JSON dari API (yang terletak di dalam Respons HTTP)
                let countries = JSON.parse(httpResponse.response);
                console.log("Kota ibu kota Jepang adalah:");
                console.log(`${countries[0].capital}`);
            });
    }
}
```

Deskripsi kode:

- Ketika seorang klien terhubung ke Ruang Multiplay, fungsi `onJoin` dipicu, dan itu memanggil `findCapitalCity`.
- Jika panggilan `getAsync` ke API restcountries berhasil, Anda dapat mengakses objek `httpResponse` di dalam `then` callback.
- Parse `httpResponse.response` untuk mengonversi respons API, yang dalam format JSON, menjadi sebuah objek.
- Dengan merujuk pada struktur respons API, Anda mengakses properti yang diinginkan dan kemudian mencetak nilainya.

Ketika Anda menjalankan server Multiplay di Editor Unity dan memainkan adegan, yang berikut akan ditampilkan di Console.

```text
Ibu kota Jepang adalah: 
Tokyo
```

### Praktik Pengkodean Defensif

- Sementara itu, seperti yang disebutkan dalam langkah-langkah pencegahan pengantar, permintaan web dapat gagal karena berbagai alasan, termasuk perubahan alamat web atau format respons API.
- Kegagalan untuk menangani permintaan ini dengan benar dapat memiliki berbagai efek buruk pada permainan Dunia, jadi disarankan untuk mengkode secara defensif, terutama saat berurusan dengan permintaan HTTP.
- Berikut adalah contoh penerapan beberapa teknik pengkodean defensif pada kode di atas.

```typescript
   findCapitalCity() {
    // Buat permintaan ke API restcountries
    HttpService.getAsync(
        "https://restcountries.com/v3.1/name/japan?fields=capital",
        { 'Accept': HttpContentType.ApplicationJson })
        // Penangan untuk Respons HTTP
        .then((httpResponse) => {
            // Periksa apakah panggilan API mengembalikan 200(OK) atau tidak
            if (httpResponse.statusCode != 200) {
                // Jika tidak 200(OK), jangan lanjutkan dan angkat kesalahan kustom
                throw (`Kesalahan API: ${httpResponse.statusCode} ${httpResponse.statusText}`);
            }
            // Kembalikan data respons JSON dari API
            return httpResponse.response;
        })
        // Penangan untuk data respons JSON dari API
        .then((response) => {
            // Parse data respons JSON
            let countries = JSON.parse(response);
            // Periksa apakah data respons API valid
            if (!Array.isArray(countries) || !countries.length) {
                // Jika bukan array, atau kosong
                // jangan lanjutkan dan angkat kesalahan kustom
                throw (`Kesalahan API: Data respons tidak valid`);
            }
            let country = countries[0];
            // Periksa apakah field 'capital' valid
            if (!country.capital) {
                // Jika field 'capital' tidak ada, atau kosong
                // jangan lanjutkan dan angkat kesalahan kustom
                throw (`Kesalahan API: field 'capital' tidak valid`);
            }
            console.log("Ibu kota Jepang adalah:")
            console.log(`${country.capital}`);
        })
        // Penangan untuk kesalahan yang terjadi dalam panggilan getAsync dan klausa 'then'.
        .catch((reason) => {
            console.log("Kesalahan Permintaan API");
            console.log(reason);
        });
}
```

Teknik pengkodean defensif yang diterapkan di sini meliputi yang berikut:

- Menggunakan `Accept` Header: `Accept` header digunakan untuk menentukan Content-Type yang diharapkan untuk body respons. Tergantung pada server, Content-Type respons dapat disesuaikan berdasarkan `Accept` header.
- Memeriksa `HttpResponse.statusCode`: Properti `HttpResponse.statusCode` digunakan untuk memverifikasi keberhasilan permintaan.
- Memvalidasi Struktur Data JSON: Anda mengonfirmasi apakah struktur data dari objek yang diparsing dengan `JSON.parse` sesuai dengan struktur yang diharapkan.
- Memverifikasi Keberadaan Properti: Anda memastikan bahwa properti yang ingin Anda gunakan benar-benar ada dalam objek.
- Memanfaatkan `catch` Metode Promise: Metode `catch` dari Promise digunakan untuk menangani kesalahan yang mungkin terjadi selama permintaan API dan pemrosesan respons.

Teknik-teknik ini melindungi kode agar beroperasi dengan andal di tengah kesalahan yang tidak terduga, meningkatkan ketahanannya.



### Mengintegrasikan dengan Klien melalui Pesan Ruangan

Permintaan HTTP hanya mungkin dilakukan dari server Multiplay.

Namun, dengan menggunakan Pesan Ruangan Multiplay, Anda dapat memicu server untuk mengirim permintaan HTTP ke layanan web eksternal dari klien dan memanfaatkan respons di dalam klien.

Contoh berikut menunjukkan integrasi klien-server. Dalam demonstrasi ini, ketika tombol pada UI klien ditekan, ibu kota negara yang sesuai dengan tombol ditampilkan.

:::hint{type="info"}
**📘&#x20;**&#x53;ilakan merujuk ke panduan berikut. \[[Proses koneksi ruangan](docId\:DXdBn6WVI82ag_wdc1thr)]
:::



![](https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-tfcubL3eArDSHrPB-D9AO-20240904-102411.gif)



**Kode Klien**

```typescript
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import { Room } from 'ZEPETO.Multiplay'
import { ZepetoWorldMultiplay } from 'ZEPETO.World';
import { Button, Text } from 'UnityEngine.UI'

export default class SampleScript extends ZepetoScriptBehaviour {

    public multiplay: ZepetoWorldMultiplay;
    public room: Room;
    public countryButtons: Button[];
    public capitalText: Text;


    Start() {
        interface Response {
            capitals: string[]
        }

        for (const countryButton of this.countryButtons) {
            countryButton.onClick.AddListener(() => {
                if (this.room !== null) {
                    // Kirim nama negara sebagai pesan tipe 'client-to-server' ke server
                    this.room.Send("client-to-server", countryButton.GetComponentInChildren<Text>().text);
                }
            });
        };

        this.multiplay.RoomCreated += (room: Room) => {
            this.room = room;
            // Tangani pesan yang diterima dengan tipe 'server-to-client'
            this.room.AddMessageHandler("server-to-client", (message: Response) => {
                // Untuk negara dengan beberapa ibu kota,
                // gabungkan elemen string dengan ', ' dan tampilkan di scene
                this.capitalText.text = message.capitals.join(", ");
            });
        };
    }
}
```

Deskripsi kode:

- Kami mendefinisikan pendengar yang mengiterasi melalui tombol yang menampilkan nama-nama negara. Ketika diklik, pendengar ini mengirim Pesan Ruangan ke server Multiplay.
- Pendengar ini mengirim nama negara yang ditampilkan pada tombol sebagai pesan tipe 'client-to-server'.
- Untuk menangani respons, kami juga mendefinisikan pendengar untuk memproses Pesan Ruangan yang diterima sebagai tipe 'server-to-client'.
- Pendengar ini menampilkan nama ibu kota yang diterima dari server di layar. Jika ada beberapa ibu kota, mereka ditampilkan di layar, dipisahkan oleh koma.



**Kode Server**

```typescript
import { Sandbox, SandboxOptions, SandboxPlayer } from "ZEPETO.Multiplay";
import { HttpService } from "ZEPETO.Multiplay.HttpService";

export default class extends Sandbox {

    onCreate(options: SandboxOptions) {
        // Tangani pesan yang diterima dengan tipe 'client-to-server'
        this.onMessage("client-to-server", (client, message) => {
            console.log(`Klien ${client.userId} mengirim permintaan. Pesan: ${message}`);
            this.findCapitalCity(message, client);
        });
    }

    onJoin(client: SandboxPlayer) { }
    onLeave(client: SandboxPlayer, consented?: boolean) { }

    findCapitalCity(countryName: string, client: SandboxPlayer) {
        // Permintaan API dengan countryName sebagai parameter jalur
        // countryName dikirim oleh klien sebagai pesan ruang
        HttpService.getAsync(`https://restcountries.com/v3.1/name/${countryName}?fields=capital`)
            .then((httpResponse) => {
                if (httpResponse.statusCode != 200) {
                    throw (`Kesalahan API: ${httpResponse.statusCode} ${httpResponse.statusText}`);
                }
                return httpResponse.response;
            })
            .then((response) => {
                let countries = JSON.parse(response);
                if (!Array.isArray(countries) || !countries.length) {
                    throw (`Kesalahan API: Data respons tidak valid`);
                }
                let country = countries[0];
                if (!country.capital) {
                    throw (`Kesalahan API: field 'capital' tidak valid`);
                }
                // Kirim pesan tipe 'server-to-client' ke klien
                // Pesan adalah objek yang berisi nama-nama ibu kota
                client.send("server-to-client", {
                    "capitals": country.capital
                });
            })
            .catch((reason) => {
                console.log("Kesalahan Permintaan API");
                console.log(reason);
            });
    }
}
```

Deskripsi kode:

- Kami mendefinisikan pendengar yang, setelah menerima pesan Ruang Multiplay tipe 'client-to-server', memanggil `findCapitalCity`.
- Kami membangun alamat untuk Pesan Ruang Multiplay menggunakan nama negara dan melakukan panggilan `getAsync` .
- Jika panggilan `getAsync` berhasil, respons ditangani seperti pada contoh sebelumnya.
- Nama ibu kota yang diperoleh dari respons API restcountries dikirim ke klien sebagai Pesan Ruang tipe 'server-to-client'.



### Permintaan POST

Terakhir, mari kita buat contoh permintaan POST menggunakan `HttpService.postAsync`.

[postman-echo](https://postman-echo.com/) adalah layanan yang menyediakan respons terstruktur yang menunjukkan konten apa yang diterima dari permintaan web, menjadikannya efektif untuk memverifikasi apakah klien telah mengonfigurasi permintaan dengan benar.

Melalui contoh ini, kita akan mengatur permintaan POST dengan parameter kueri, badan permintaan, dan header serta memastikan bahwa permintaan dikonfigurasi dengan benar.

Siapkan Multiplay, lalu buka World.multiplay/index.ts dan tulis skrip server sebagai berikut.

```typescript
import { Sandbox, SandboxOptions, SandboxPlayer } from "ZEPETO.Multiplay";
import { HttpContentType, HttpService } from "ZEPETO.Multiplay.HttpService";

export default class extends Sandbox {

    onCreate(options: SandboxOptions) { }
    onJoin(client: SandboxPlayer) { this.echoPost() }
    onLeave(client: SandboxPlayer, consented?: boolean) { }

    echoPost() {
        HttpService.postAsync(
            // API Endpoint dengan parameter kueri
            "https://postman-echo.com/post?argKey=argValue",
            // JSON Request Body
            { "dataKey": "dataValue" },
            // Jenis Konten Permintaan
            HttpContentType.ApplicationJson,
            // Header HTTP
            { "header-key": "header-value" })
            .then((httpResponse) => {
                if (httpResponse.statusCode != 200) {
                    throw (`Kesalahan API: ${httpResponse.statusCode} ${httpResponse.statusText}`);
                }
                return httpResponse.response;
            })
            .then((response) => {
                let parsed = JSON.parse(response);
                console.log(`Parameter kueri: argKey:${parsed.args.argKey}`);
                console.log(`Isi permintaan: dataKey:${parsed.data.dataKey}`);
                console.log(`Header permintaan: header-key:${parsed.headers["header-key"]}`)
            })
            .catch((reason) => {
                console.log("Kesalahan Permintaan API");
                console.log(reason);
            });
    }
}
```

Deskripsi kode:

- Ketika klien terhubung ke Ruang Multiplay, `echoPost` fungsi dipanggil dari `onJoin` pemicu.
- Saat membuat `postAsync` permintaan:
  - Pada parameter pertama, kami membangun string URL dengan parameter kueri.
  - Pada parameter kedua, kami mengatur konten tubuh permintaan.
  - Pada parameter keempat, kami mengonfigurasi header permintaan.
  - Untuk menentukan bahwa tubuh permintaan dalam format JSON, kami mengatur 'application/json' Content-Type di parameter ketiga.
- Jika `postAsync` panggilan berhasil, kami dapat mengakses `httpResponse` objek di `then` callback.
- Kami mengurai `httpResponse.response` untuk mengonversi respons API dalam format JSON menjadi objek.
- Merujuk pada struktur respons API, kami menggunakan output Console untuk memverifikasi apakah parameter kueri permintaan HTTP kami, tubuh permintaan, dan header permintaan telah dikonfigurasi dengan benar.

Ketika Anda menjalankan server Multiplay di Editor Unity dan memainkan adegan, yang berikut akan ditampilkan di Konsol.

```text
Parameter kueri: argKey:argValue
Badan permintaan: dataKey:dataValue
Header permintaan: header-key:header-value
```

