Halo cuy ! Karena gue rasa penting mempelajari apa itu RESTful API dalam dunia coding, jadi gue mutusin buat lebih serius memahaminya, walaupun sistem yang biasa gue bangun kebanyakan masih monolit, baik ngoding santai maupun kerjaan kantor. Dikantor gue juga gue sempet berkolaborasi dan megang bagian yang berurusan dengan API walaupun gue cuman "nembak" endpoint gak bikin API-nya sendiri, itu cukup bikin gue penasaran untuk mempelajarinya. OKE LANGSUNG AJA !
Secara fungsi API membantu pengembang membuat aplikasi lebih cepat dan efisien dengan memanfaatkan fitur atau layanan yang sudah tersedia dari aplikasi lain, misalnya melalui API publik. Dengan API, pengembang tidak perlu membangun semua fitur dari nol karena aplikasi dapat terhubung dengan sistem eksternal seperti pembayaran, peta, atau data cuaca. Selain mempercepat proses pengembangan, API juga memudahkan integrasi antar aplikasi karena layanan dapat dibuat secara modular dan digunakan oleh berbagai sistem yang berbeda. Biasanya API diimplementasikan melalui Web Service agar dapat terhubung dan digunakan oleh Aplikasi atau Client berbeda.
Lalu pertanyaannya apa itu RESTful API?. Sebelumya memahami apa itu, penting untuk mengetahui terlebih dahulu apa itu API,Interface dan REST API pada sistem/komputer, jadi apa itu ?
- "API (Application Programming Interface) adalah sekumpulan fungsi, subroutine, protocol komunikasi atau alat untuk membuat perangkat lunak. yang memungkinkan aplikasi perangkat lunak untuk berkomunikasi satu sama lain untuk bertukar data, fitur, dan fungsionalitas" API tidak terbatas pada web development saja. Library, framework, sistem operasi, database, hingga driver hardware juga dapat menyediakan API agar dapat digunakan oleh aplikasi lain.
- Terdapat kata Interface pada API . "Interface Bagian yang sama antara dua atau lebih komponen terpisah pada sebuah sistem komputer." Tujuannya untuk saling terhubung satu sama lainnya.
- REST API (Representasional State Transfer), adalah gaya perancangan atau arsitektur transfer keadaan representasional (REST), gaya yang digunakan untuk menghubungkan sistem hypermedia terdistribusi. arsitektur stateless, REST API terkadang disebut sebagai RESTful API atau RESTful web API.
Lalu apa itu RESTful API? sebelum masuk ada lagi hal penting yang harus dipahami, yaitu cara kerja HTTP. karena REST API hampir selalu menggunakan HTTP, yang perlu dipahami disini REST API != HTTP, karena REST API itu gaya arsitektur bukan protokol, dan REST API tidak terikat dengan protokol HTTP.
Gue sendiri juga belum terlalu dalem mempelajari implementasi REST di luar HTTP karena di dunia nyata hampir semuanya pakai HTTP, jadi ya lebih baik fokus ke HTTP saja.
Cara kerja HTTP
Contoh penggunaan HTTP saat kita mengetikan alamat website seperti facebook.com atau instagram.com browser melakukan Request yang secara default browser menggunakan Method GET, dan server menerima Request tersebut dan mengembalikan Response yang pada umumnya berupa HTML ke client. Contoh kasus ketika mengakses halaman utama yaitu personal-blog.test/
Disisi Server Request diterima dan Mengembalikan dalam bentuk HTML/ Halaman Home.
Route::prefix('categories')->name('categories.')->group(function () {
Route::get('/', [CategoryController::class, 'index'])
->name('index');
});
Contoh lainnnya didalam Form HTML ketika kita melakukan submit, disini terjadi Reqest Response HTTP, biasanya menggunakan Method POST, dan juga mengirimkan data yang disisipkan di body Reqeuest. Contoh kasus ketika melakukan Submit Form Edit Categories pada Blog.
Route::prefix('categories')->name('categories.')->group(function () {
Route::put('/{category}', [CategoryController::class, 'update'])
->name('update');
});
Ada hal unik yang terjadi terkait method pada browser, Melalui Browser Navigation URL dan Form HTML native hanya mendukung method GET dan POST. dengan menggunakan fetch/ajax Javascript kita baru bisa menggunakan Method PUT, PATCH dll. Lalu kenapa pada menu Category tersebut terdapat Method PUT dll? itu karena Framework seperti CI/Laravel mengatasinya dengan menyisipkan input method pada Form sehingga kita dapat melakuan Request Selain GET dan POST, walaupun sebenarnya disisi browser tetap menggunakan Method POST hanya saja Framework yang menginterpresentasikannya sebagai method PUT. bisa dilihat gambar dibawah terdapat input hidden dengan name="_method" dan value ="PUT"

Jadi disini bisa dilihat dengan jelas Cara kerja HTTP, yaitu Client melakukan Request dengan Method GET/POST dan Server Mengembalikan data berupa HTML atau Lainnya.
Lalu untuk apa menggunakan API jika menggunakan Sistem Monolit seperti ini sudah bisa berjalan? oke sabar... kita masuk ke Ilustrasi REST API terlebih dahulu :).
Ilustrasi REST API
Rest API sering kali diilustrasikan sebagai Kegiatan yang ada di restoran, kita sebagai customer bisa di anggap (sebagai client/requester), yang pesanannya atau (Requestnya) akan di terima oleh pelayan yang bisa dianggap (sebagai API) "perantara" yang kemudian akan di proses oleh dapur (Server), yang jika dapur sudah menyelesaikan pesananya maka akan memberikan Pesanan Makanan ke Pelayan, yang nanti akan diterima Customer sebagai Response berupa makanan.

Dari ilustrasi tersebut terlihat biasa bukan? lalu apa bedanya dengan request website tradisional? Perbedaan utama website tradisional dan REST API terletak pada bentuk response yang diberikan server. Pada website tradisional, server biasanya mengirimkan HTML yang siap ditampilkan browser. Sedangkan pada REST API, server umumnya hanya mengirimkan data mentah seperti JSON yang nantinya diolah lagi oleh client atau frontend.
REST API adalah aturan komunikasi antara client dan server yang membuat request dan response memiliki struktur yang jelas. Dalam analogi restoran, REST API bisa diibaratkan seperti menu restoran yang menentukan apa saja yang bisa dipesan oleh customer. Customer tidak bisa meminta sesuatu di luar menu yang tersedia, sama seperti client tidak bisa melakukan request ke endpoint yang tidak disediakan server. Setiap menu juga memiliki aturan yang jelas, misalnya cara pemesanan dan hasil yang akan diberikan, seperti endpoint API yang memiliki URL, method, dan format response tertentu.
Jadi REST API itu jelas adalah aturan, lalu apa bedanya REST API vs RESTful API ?
jika dianalaogin dalam restoran itu seperti ini
- REST = aturan restoran & sistem pemesanan
- REST API = restoran yang menggunakan aturan
- RESTful API = restoran yang benar-benar menjalankan aturan tersebut
jadi terlihat bedanya? aturan disini mengacu pada prinsip REST contohnya
- Menggunakan HTTP method dengan benar
- URI/endpoints-nya menggunakan kata benda
- stateless
- dll
Pada RESTful API itu tidak ada standarisasi teknisnya, tetapi API dapat dikatakan RESTful jika berusaha mengacu pada prinsip-prinsip REST yang dijelaskan oleh Roy Fielding dalam disertasi doktoralnya pada tahun 2000 yang berjudul Architectural Styles and the Design of Network-based Software Architectures.
Contoh tidak RESTful API.
(ini bukan REST API murni ini sistem di blog ini buat analogi aja)
Ketika kita melakukan Request untuk update Category dengan method PUT. setelah submit kita diarahkan ke halaman index Category atau list Category.
Dari sisi server melakukan proses Update pada categories yang dipilih, dengan contoh Laravel Endpoint dan Route seperti ini. PUT /categories/1
Route::prefix('categories')->name('categories.')->group(function () {
Route::put('/{category}', [CategoryController::class, 'update'])
->name('update');
});
Disini endpoint sebenarnya sudah mengikuti prinsip REST seperti penggunaan method PUT dan URI berbasis resource (/categories/{category}), namun implementasinya masih lebih berorientasi ke web application karena response yang dikembalikan masih berupa HTML/view, bukan data JSON seperti REST API modern pada umumnya.
Jadi sudah nangkep kan apa itu RESTful API ? oke itu adalah pemahaman yang harus dipahami terkair RESTful API, untuk tahap selanjutnya kita bedah terkait implementasi RESTful API dari aspek HTTP.
Aspek HTTP pada RESTful API
kenapa HTTP?
Seperti yang dijelaskan sebelumnya RESTful API itu arsitektural style, bukan protokol, jadi tidak ada keharusan menggunakan HTTP secara mutlak, dan kenapa lebih sering HTTP kenapa tidak pakai protokol lain ?
- Server dan Client bisa dibuat dibahasa pemrograman apapun
- Stateless, sehingga mudah untuk di scale di sisi server
- Sangat familiar dengan programmer,
- Mudah ditest dan mudah digunakan
HTTP Header
HTTP Header adalah informasi tambahan yang bisa dikirim oleh client atau server, Informasi metadata atau informasi teknis yang bukan bagian utama dari resource/data biasanya lebih cocok dikirim melalui HTTP Header. Dan HTTP Header itu bisa ditulis diluar standar sesuai dengan kebutuhan, tapi tetap direkomendasikan menggunakan HTTP Header yang sudah ada (standar), HTTP header itu bentuknya Key dan Value. Contoh nya ketika ada Aplikasi Mobile, dan untuk mengirimkan Versi Aplikasi Mobile itu sebaiknya jangan gunakan Body atau Query Parameter tapi gunakan HTTP Header karena itu tidak ada kaitannya dengan resource/data.
Accept
Accept header pada HTTP digunakan client untuk memberi tahu server. Dalam RESTful API, biasanya client meminta data dalam bentuk JSON. Contoh.
Request Accept: application/json
Response Content-Type: application/json
Content Type
Content type bergantung pada server, jadi jika Request Accept: text/html belum tentu Responsenya Content-Type: text/html bisa saja Content-Type: application/json yang diterima.
-
Accept→ client bilang: “Saya ingin menerima data format apa.” -
Content-Typepada request → client bilang “Data yang saya kirim ke server formatnya apa.” ini bisa ada di Request dan Response.
Accept-Language
Accept-Language: en-USAccept-Language: id-ID
- Accept-Language adalah HTTP Header yang digunakan oleh client untuk memberi tahu bahwa client menginginkan response dengan bahasa tertentu
- Biasanya jika di browser, Accept-Language akan mengikuti language sistem operasi atau aplikasi browser nya
- Contoh nilai Accept-Language seperti en-US, id-ID, dan lain-lain
User-Agent, Referer, dan Lain - Lain. (masih banyak header lainnya)
HTTP Response Code
- HTTP Response Code adalah kode response yang dikembalikan oleh server untuk memberi tahu status dari request yang dikirim oleh client
- HTTP Response code memiliki standard untuk jenis response tertentu
- Dalam membuat RESTful API, usahakan gunakan HTTP Response Code yang sudah tersedia, jangan membuat response code baru atau berbeda dari biasanya
Berikut Groping Response Code berdasarkan Kepalanya.
| Response Code | Arti |
|---|---|
| 1xx | Informasi bahwa request sedang diproses |
| 2xx | Request berhasil diproses |
| 3xx | Redirect atau perpindahan resource |
| 4xx | Kesalahan pada request dari client |
| 5xx | Kesalahan pada server |
Pada RESTful API, HTTP Response Code yang paling sering digunakan biasanya adalah 2xx, 4xx, dan 5xx. Pada RESTful API Selau gunakan Status Code yang standar misalnya ketika Create Data pastikan API mengembalikan 201 Created untuk Response Codenya. Dan Ketika Update Data Pastikan Response Codenya 204 No Content.
Pada RESTful API, selalu gunakan HTTP Status Code standar sesuai kondisi response. Contoh :
200 OK→ update berhasil + ada response body
{
"message": "User updated"
}
204 No Content→ update berhasil tanpa response body
Sesuaikan status code dengan isi response dan kondisi request.
HTTP Method
HTTP Method adalah metode permintaan dari client, untuk menunjukkan tindakan yang diinginkan yang akan dilakukan ke server. Method pada HTTP ada banyak, tapi hanya ada beberapa saja yang umum atau sering digunakan, sebagai berikut :
| HTTP Method | Keterangan |
|---|---|
| GET | Meminta data dari server |
| POST | Mengirim data ke server |
| PUT | Mengubah seluruh data yang sudah ada di server |
| PATCH | Mengubah sebagian data yang sudah ada di server |
| DELETE | Menghapus data yang sudah ada di server |
Jika ditransform ke Method terkait kesesuaian dengan Prinsip RESTful API maka seperti ini.
| HTTP Method | Keterangan |
|---|---|
| GET | Mengambil atau mencari record di server |
| POST | Membuat record baru di server |
| PUT | Mengubah seluruh atribut record yang sudah ada di server |
| PATCH | Mengubah sebagian atribut record yang sudah ada di server |
| DELETE | Menghapus record di server |
URL (Uniform Resource Locator)
URL adalah alamat yang digunakan di web untuk mengakases sebuah resource, disini harus diperhatikan untuk membuat RESTful API URL juga harus dibuat dengan baik. Struktur URL.

HTTP Message
HTTP Message adalah bagaimana data bertukar dari client dan server, Ada 2 tipe message :
- Message yang dikirim oleh client
- Message yang dikembalikan oleh server
HTTP Message memiliki format standard seperti berikut ini :

Authentication dan Authorization
Pada RESTful API pada umumnya terdapat mekanisme Authentication dan Authorization, ada kalanya kita mengamankan RESTful API dan membatasi pihak mana yang boleh mengakses RESTful API. Untuk detailnya :
- Authentication adalah proses verifikasi identitas seseorang atau sistem sebelum diberikan akses. Misalnya, ketika memasukkan kata sandi untuk masuk ke dalam sistem, sistem akan memeriksa apakah informasi tersebut cocok dengan data yang tersimpan. Jika sesuai, kamu diizinkan masuk.
- Sedangkan Authorization adalah proses yang menentukan hak akses seseorang setelah mereka berhasil diautentikasi. Misalnya, dalam sebuah sistem perbankan, setelah masuk ke akun, kita bisa melihat saldo dan melakukan transfer, tetapi tidak bisa mengakses data nasabah lain.
Contoh mekanisme Authentication yang umum digunakan pada RESTful API antara lain Basic Authentication, API Key, OAuth 2.0. Setelah proses Authentication berhasil, Authorization digunakan untuk menentukan hak akses yang dimiliki oleh pengguna atau sistem, misalnya melalui Role, Permission, Policy, atau Scope.
Contoh Authentication dan Authorization
- Basic Auth

Basic Authentication adalah mekanisme Authentication sederhana yang menggunakan username dan password. Kredensial tersebut dikirim melalui header Authorization pada setiap request. Ini jarang digunakan diaplikasi Mobile Apps atau Client. Basic Authentication jarang digunakan pada aplikasi mobile maupun Single Page Application (SPA). Hal ini karena aplikasi harus menyimpan username dan password pengguna atau kredensial aplikasi. Jika terjadi kesalahan implementasi atau kredensial berhasil diekstrak dari aplikasi, pihak lain dapat memperoleh akses menggunakan kredensial tersebut.
Oleh karena itu, aplikasi modern umumnya lebih memilih menggunakan OAuth 2.0 karena kredensial utama tidak perlu dikirim pada setiap request dan akses dapat dibatasi melalui masa berlaku token maupun hak akses tertentu.
Contoh : Authorization: Basic base64(username:password)
- API-Key

Authentication sederhana yang menggunakan API Key atau Secret Key sebagai identitas aplikasi yang mengakses API. API Key dikirim melalui header request dan akan diverifikasi oleh server sebelum akses diberikan. Umumnya digunakan pada komunikasi Server-to-Server, integrasi antar aplikasi, atau API internal. Implementasinya sederhana, namun jika API Key bocor maka pihak lain dapat mengakses API hingga key tersebut dicabut atau digenerate ulang.
Contoh: API-Key: random-api-key-urnod2i3unr8qy78n8nrf83ufior2u3fior
- OAuth 2.0

OAuth 2.0 adalah authorization yang memungkinkan sebuah aplikasi memperoleh akses terbatas ke resource milik pengguna tanpa perlu mengetahui username dan password pengguna tersebut. OAuth 2.0 bekerja dengan memberikan Access Token kepada aplikasi setelah pengguna berhasil melakukan autentikasi dan memberikan persetujuan akses.
Contoh penggunaan:
• Login dengan Google
• Login dengan GitHub
• Login dengan Microsoft
Alur sederhananya:
Client meminta login → User melakukan login → Server memberikan Access Token dan Refresh Token → Client menggunakan Access Token untuk mengakses API → Access Token expired → Client mengirim Refresh Token → Server memberikan Access Token baru → Client kembali mengakses API
OAuth 2.0 umumnya digunakan pada aplikasi Client-Server, Mobile Apps, Single Page Application (SPA), serta integrasi antar sistem yang memerlukan akses terbatas terhadap resource pengguna. OAuth 2.0 lebih aman dibanding memberikan username dan password secara langsung karena aplikasi hanya menerima token akses dengan hak akses dan masa berlaku tertentu.
- dan lain lain
Dari penjelasan tersebut dapat disimpulkan bahwa tidak ada satu mekanisme Authentication dan Authorization yang paling baik untuk semua RESTful API. Pemilihannya bergantung pada kebutuhan, tingkat keamanan, serta arsitektur sistem yang dibangun, baik untuk komunikasi Client-Server maupun Server-to-Server.
Resource Naming
Resource Naming adalah cara memberikan nama pada resource (sumber daya/data) di dalam URI atau endpoint API. Resource dalam RESTful API adalah data yang sifatnya bisa satu atau banyak. Misal, “customers” adalah kumpulan dari “customer”, dimana “customer” adalah satu data customer.
Resource Naming pada RESTful API praktiknya sebagai berikut:
Gunakan Kata Benda, Bukan Kata Kerja
Contoh Benar ✅:
-
http://api.example.com/products
-
http://api.example.com/members
Contoh Salah ❌:
-
http://api.example.com/get-all-products
-
http://api.example.com/select-members-table
Gunakan Hirarki
Gunakan hirarki untuk menggambarkan hubungan antar resource, bukan untuk setiap atribut data.
Contoh Benar ✅:
-
http://api.example.com/products/{productId}/images
-
http://api.example.com/merchants/{merchantId}/addresses
Contoh Salah ❌ :
-
http://api.example.com/product-images/{productId}
-
http://api.example.com/merchant-addresses/{merchantId}
Contoh kasus lanjutan Merchant-Address
Dalam mendesign Resouce name tidak selalu sesimpel mendesign 1 objek / entitas, ambil contoh kasus berikut :
Merchant
└── Address
merchants
---------
id
name
addresses
---------
id
merchant_id
address
Dari kasus tersebut jika dibuatkan API yang RESTful maka seperti ini.
Contoh benar ✅
GET /merchants/1/addresses
POST /merchants/1/addresses
GET /merchants/1/addresses/6
GET /addresses/6
PUT /addresses/6
DELETE /addresses/6
Contoh Salah ❌
GET /merchant-addresses/1
POST /merchant-addresses/1
GET /merchant-addresses/6
GET /address/6
PUT /update-address/6
DELETE /delete-address/6
// mengakses attribute
GET /addresses/6/city
GET /addresses/6/province
GET /addresses/6/postal-code
Nah disini cara mendesign Nama Resource bisa saja jadi kompleks, pada kasus tersebut terbentuk 2 cara jika mengacu untuk mengakses Address, pertama lewat Nested Resource /merchants/{id}/addresses atau Global Resource /addresses.
Gunakan hirarki untuk menggambarkan hubungan antar resource, bukan untuk setiap atribut data.
Misalnya
Merchant ← Resource
Address ← Resource
city ← atribut
province ← atribut
postal_code ← atribut
Karena itu tidak perlu membuat hirarki seperti :
GET /addresses/6/city
GET /addresses/6/province
GET /addresses/6/postal-code
yang benar cukup :
GET /addresses/6
Response :
{
"id": 6,
"merchant_id": 1,
"address": "Jl. Sudirman",
"city": "Medan",
"province": "Sumatera Utara",
"postal_code": "20111"
}
Selalu gunakan format konsisten pada Naming Resource contoh salah menggunakan Address dan Addresses pada API yang sama, selalu gunakan 1 format saja singular/plural, disini tidak ada kewajiban memkai yang mana harus dipakai, tapi selalu pastikan pakai gunakan format yang konsisten. Seracara umum RESTful API kebanyakan menggunakan format Plural pada implementasinya.
Ketika mendesain hirarki REST, pertanyaan: "Apakah objek ini punya ID sendiri dan bisa diakses sendiri?"
Bisa diterjemahkan menjadi: "Apakah rela membuat endpoint CRUD khusus untuk objek ini?"
Gunakan Action Pada Resource
Tidak semua operasi dapat direpresentasikan dengan baik sebagai CRUD terhadap resource., berkaitan dengan aturan "gunakan kata benda pada resource". Karena tidak semua operasi itu CRUD terhadap resource, berikut beberapa operasi yang bukan CRUD terhadap resource.
- Login
- Logout
- Reset Password
- Verify Email
- Activate Account
- Change Password
Operasi seperti ini lebih merupakan aksi (action) dari pada operasi CRUD pada resource. Selalu terapkan action di bawah resource yang relevan.
Contoh Benar ✅:
-
http://api.example.com/users/login
-
http://api.example.com/users/forget-password
Contoh Salah ❌:
-
http://api.example.com/login-user
-
http://api.example.com/forget-password-user
Gunakan - dan lowercase
Contoh Benar ✅:
-
http://api.example.com/products/{productId}/warehouse-locations
Contoh Salah ❌:
-
http://api.example.com/products/{productId}/warehouse_locations
-
http://api.example.com/products/{productId}/warehouseLocations
Gunakan CRUD pada HTTP Method
Contoh Benar ✅:
-
GET http://api.example.com/products/{productId}
-
POST http://api.example.com/products
Contoh Salah ❌:
-
GET http://api.example.com/get-products-by-id/{productId}
-
POST http://api.example.com/create-product
Gunakan Query untuk Filter
Contoh Benar ✅:
-
http://api.example.com/products?name=Indomie
-
http://api.example.com/products?name=Indomie&page=10
Contoh Salah ❌:
-
http://api.example.com/products/filter-by-name/{name}
-
http://api.example.com/products/page/1
Versioning
Saat membuat RESTful API, usahakan untuk tidak merusak kompatibilitas (backward compatibility) ketika melakukan perubahan atau upgrade API.
Versioning sebaiknya hanya digunakan ketika perubahan yang dilakukan memang menyebabkan client lama tidak dapat menggunakan API dengan cara yang sama seperti sebelumnya (breaking change).
Sebisa mungkin hindari kondisi ini, karena biaya (cost) yang ditimbulkan cukup besar. Client yang sudah menggunakan API tersebut harus melakukan perubahan pada aplikasi yang sudah berjalan agar tetap dapat berkomunikasi dengan API versi terbaru.
Namun jika breaking change memang tidak dapat dihindari, maka kita perlu membuat versi baru dari API tersebut (API Versioning) agar client lama tetap dapat menggunakan versi sebelumnya tanpa terganggu. backward compatibility sangat dijaga dan versioning biasanya menjadi pilihan terakhir.
Ada 2 Cara umum pada Versioning :
Versioning Pada URL
- http://api.example.com/v1/products
- http://api.example.com/v2/products
- http://api.example.com/2019/products
- http://api.example.com/2020/products
Versioning Menggunakan HTTP Header
- HTTP Header => API-Version : 1
- HTTP Header => API-Version : 2
- HTTP Header => X-API-Version : 201
- HTTP Header => X-API-Version : 2020
RESTful API yang baik semaksimal mungkin tidak merusak API. Sehingga sebenarnya tidak butuh membuat API versi baru. jadi ketika maintanance itu sebaiknya tidak merusak kompabilitas dan hanya melakukan perbahan yang tidak merusak API seperti menambahakan field, meningkatkan peforma, fix bug, meningkatkan keamanan, menambahkan endpoint baru, dll.
JSON
JSON (JavaScript Object Notation) adalah format pertukaran data yang digunakan untuk mengirim, menerima, dan menyimpan data secara terstruktur. Meskipun berasal dari sintaks object pada JavaScript, JSON dapat digunakan oleh berbagai bahasa pemrograman.
Pada RESTful API, format data yang paling umum digunakan adalah JSON. Meskipun REST tidak mewajibkan penggunaan JSON, format ini sangat direkomendasikan karena ringan, mudah dibaca oleh manusia, dan didukung oleh hampir semua bahasa pemrograman. contoh :
{
"id": 1,
"name": "Junaedi",
"email": "junaedi@example.com",
"phone": "081234567890",
"is_active": true
}
Fomat JSON Konsisten
-
Tidak seperti SOAP yang format request dan response nya sudah ditentukan, menggunakan RESTful API tidak ada standar baku dalam membuat request dan response
-
Menggunakan JSON jika tidak dibuat dengan baik bisa terlalu liar, karena memang bisa dibuat sesuka kita
-
Disarankan untuk membuat standard request dan response agar tidak membingungkan ketika menggunakan RESTful API yang kita buat
-
Response JSON yang dinamis akan sangat menyulitkan client terutama yang menggunakan bahasa pemrograman static typed
Contoh tidak Baik ❌
Formatnya berubah ubah tiap response.
GET /users/1
{
"id": 1,
"name": "Junaedi"
}
GET /products/1
{
"success": true,
"data": {
"id": 1,
"name": "Laptop"
}
}
GET /orders/1
{
"result": {
"id": 1,
"total": 500000
}
}
Contoh Baik ✅
GET /users/1
{
"success": false,
"message": "User tidak ditemukan"
}
GET /products/1
{
"success": true,
"data": {
"id": 1,
"name": "Laptop"
}
}
GET /orders/1
{
"success": true,
"data": {
"id": 1,
"total": 500000
}
}
JSON API
Saat menentukan standar format JSON, kadang sering terjadi perdebatan antar programmer. JSON API adalah salah satu format standard untuk JSON yang bisa digunakan. Format di JSON API sudah mendukung HATEOAS. https://jsonapi.org/.
HATEOAS
HATEOAS singkatan dari Hypermedia as the Engine of Application State. Hypermedia artinya content yang memiliki link menuju resource yang ada.
Biasanya URL API pada RESTful API sudah di hardcode di Client. Dengan menggunakan HATEOAS, client bisa secara dinamis mendapatkan URL lokasi resource dari response data Server.
Contoh ketika GET /accounts/123456789.
Tanpa HATEOAS ❌
{
"account_number": "123456789",
"owner_name": "Junaedi",
"balance": 5000000
}
Maka client harus sudah mengetahui endpoint-endpoint tersebut:
/accounts/123456789/transactions
/accounts/123456789/transfers
/accounts/123456789/cards
Dengan HATEOAS✅
{
"account_number": "123456789",
"owner_name": "Junaedi",
"balance": 5000000,
"_links": {
"self": {
"href": "/accounts/123456789"
},
"transactions": {
"href": "/accounts/123456789/transactions"
},
"transfer": {
"href": "/accounts/123456789/transfers"
},
"cards": {
"href": "/accounts/123456789/cards"
}
}
}
Client cukup membaca:
{
"_links": {
"transactions": {
"href": "/accounts/123456789/transactions"
}
}
}
Contoh kasus menarik ketika rekening diblokir.
{
"account_number": "123456789",
"status": "BLOCKED",
"_links": {
"self": {
"href": "/accounts/123456789"
},
"unblock": {
"href": "/accounts/123456789/unblock"
}
}
}
Perhatikan transfer,withdraw,payment tidak muncul dari Response saja Client sudah tau, aksi yang tersedia hanya membuka blokir rekening. Di sinilah kata Hypermedia as the Engine of Application State menjadi masuk akal. Links disini tidak ada format standar jadi bisa saja ditulis _links , links, link atau bahkan resources, navigation.
Caching
Secara sederhana cache adalah data bersifat sementara yang disimpan pada sistem penyimpanan. Dalam RESTful API, data cache biasanya disimpan di client (misal di web browser, atau di mobile app) Fokus Cache pada RESTful API itu Client Cache, yang dikendalikan melalui HTTP Header. Cache biasa digunakan untuk menurunkan jumlah data transfer antara client dan server sehingga proses komunikasi lebih cepat. Cache menyimpan response HTTP yang kemungkinan akan diminta kembali di masa depan, baik response tersebut berupa JSON, gambar, CSS, JavaScript, HTML, maupun jenis data lainnya.

Idempotance
Dalam RESTful API, ketika membuat multiple request yang identik, harus memiliki efek yang sama seperti membuat satu request. Dalam hal ini, maka RESTful API kita bisa dibilang idempotent. Idempotent itu sangat penting, karena saat membuat RESTful API, kita akan melakukan komunikasi antara client dan server via network, sehingga error bisa terjadi. Belum lagi, banyak framework atau library client yang bisa secara otomatis melakukan request ulang ketika terjadi error pada network. Efek yang sama yang dimaksud itu bukan mengacu pada Response tapi impact di sisi servernya.
Implementasi Idempotent di RESTful API
Secara default HTTP method sudah idempotance, lalu kenapa di prinsip RESTful API di tegaskan ulang? Karena banyak developer membuat implementasi yang secara method terlihat benar tetapi perilakunya tidak idempotent. jadi konteksnya lebih ke prilakunya implementasi bukan methodnya.
Implementasi GET
Contoh Benar ✅
Jika melakuan GET method 2x GET /articles/10 Response ke-1 dan ke-2 harusnya menjamin GET tersebut tidak mengubah state server.
{
"id": 10,
"title": "Memahami RESTful API",
"views": 101
}
Contoh Salah❌
Contoh yang Sering Terjadi (Tidak Idempotent) . Jika melakuan GET method 2x GET /articles/10. Dan endpoint GET tersebut secara internal melakukan (views = views + 1).
Response ke-1
{
"id": 10,
"title": "REST API",
"views": 101
}
Responseke-2
{
"id": 10,
"title": "REST API",
"views": 102
}
Disini mungkin terlihat tidak idempotent karena request GET yang identik menghasilkan response yang berbeda, terlihat pada nilai views yang awalnya 101 menjadi 102. Namun permasalahannya sebenarnya bukan pada response yang berbeda tersebut. Response justru sudah benar karena merepresentasikan kondisi resource saat ini. Yang menjadi masalah adalah state pada API server berubah akibat request GET itu sendiri. Dengan kata lain, request yang identik menghasilkan state server yang berbeda, bukan sekadar response yang berbeda. Perubahan state inilah yang melanggar prinsip idempotency.
Kenapa konsep ini dibuat? karena jika ada runtutan dengan kasus seperti ini.
- Server menerima request.
- Server mengirim response.
- Tetapi internet putus.
- Client tidak menerima response.
- Client berpikir "Mungkin request gagal"
- Lalu otomatis melakukan retry: GET /articles/10
- GET views++ lagi
Padahal user hanya membuka artikel sekali tapi views bertambah 2x. Inilah alasan utama idempotency ada: agar request yang diulang karena retry, timeout, refresh browser, cache validation, crawler, dan lain-lain tidak mengubah hasil akhir sistem secara tidak sengaja. Seharusnya untuk mencatat views itu dilakukan di Request yang berbeda setelah GET dengan POST /articles/10/views.
"Kalau increment view dipisah ke POST, bagaimana kalau GET berhasil tetapi POST gagal? Bukankah view jadi tidak tercatat?"
Ini memang trade-off yang sering muncul pada sistem artikel, blog, berita, dan media online. Tetapi alasan banyak sistem tetap memisahkan konsidi tersebut dari GET adalah karena mereka lebih mementingkan Konsistensi HTTP Semantics.
daripada akurasi view 100%, karena view sebenarnya hanyalah statistik. Kalau hilang 1-2 view: Walaupun dari sisi bisnis mungkin lebih praktis jika disatukan, karena statistik dianggap "best effort". Bahkan banyak website besar sebenarnya sengaja melanggar prinsip GET yang murni demi kemudahan pencatatan statistik. Itu bukan berarti sistemnya salah, hanya berarti mereka mengorbankan sedikit kemurnian REST untuk kebutuhan bisnis tertentu.
Implementasi POST
Contoh Benar ✅
POST digunakan untuk membuat resource baru atau menjalankan suatu aksi pada server.
Misalnya: POST /orders Request pertama:
{
"order_id": 1001,
"product_id": 10,
"qty": 1
}
Jika request yang sama dikirim kembali: POST /orders Maka server dapat membuat order baru:
{
"order_id": 1002,
"product_id": 10,
"qty": 1
}
Perilaku ini benar karena POST secara default memang tidak bersifat idempotent. Setiap request dianggap sebagai aksi baru yang harus diproses oleh server.
Kenapa Perlu Diperhatikan? Misalnya terjadi kondisi seperti berikut
- Client mengirim POST /orders
- Server berhasil membuat Order #1001
- Server mengirim response
- Koneksi internet terputus
- Client tidak menerima response
- Client menganggap request gagal
- Client melakukan retry
- Server membuat Order #1002
Padahal pengguna sebenarnya hanya melakukan satu kali pemesanan. Akibatnya terbentuk dua order yang berbeda: Order #1001 dan Order #1002. inilah alasan mengapa POST perlu mendapatkan perhatian khusus ketika terdapat kemungkinan retry akibat timeout, gangguan jaringan, atau kegagalan menerima response.
Cara Mengatasinya
Salah satu solusi yang umum digunakan adalah Idempotency Key. Client mengirim request:
POST /orders
Idempotency-Key: abc123
{
"product_id": 10,
"qty": 1
}
Server menyimpan bahwa key abc123 sudah digunakan untuk membuat Order #1001. Jika client melakukan retry dengan key yang sama:
POST /orders
Idempotency-Key: abc123
{
"product_id": 10,
"qty": 1
}
Server tidak membuat order baru, melainkan mengembalikan hasil dari request sebelumnya. Dengan demikian: Request pertama -> Order #1001 Retry -> Tetap Order #1001
Berbeda dengan GET, PUT, dan DELETE yang secara alami bersifat idempotent, POST tidak menjamin bahwa request yang sama akan menghasilkan state yang sama. Oleh karena itu, endpoint POST yang berhubungan dengan transaksi penting seperti pembuatan order, pembayaran, atau pengiriman data biasanya memerlukan mekanisme tambahan seperti Idempotency Key untuk mencegah duplikasi akibat retry.
Implementasi PUT&PATCH
Contoh Benar ✅
PUT dan PATCH digunakan untuk memperbarui resource yang sudah ada. Misalnya terdapat data user:
{
"id": 1,
"name": "Budi"
}
Kemudian client mengirim request:
PUT /users/1
{
"name": "Andi"
}
Jika request yang sama dikirim kembali:
PUT /users/1
{
"name": "Andi"
}
Maka hasilnya tetap:
{
"id": 1,
"name": "Andi"
}
Walaupun request dieksekusi berkali-kali, state akhir resource tetap sama. Inilah yang membuat PUT bersifat idempotent.
Hal yang sama berlaku untuk PATCH jika digunakan untuk mengubah nilai resource ke kondisi tertentu.
PATCH /users/1
{
"name": "Andi"
}
Request tersebut dapat dikirim berkali-kali dan state akhirnya tetap:
{
"id": 1,
"name": "Andi"
}
Contoh Salah ❌
Kesalahan yang sering terjadi adalah menggunakan PUT atau PATCH untuk melakukan operasi penambahan nilai. Misalnya:
PATCH /articles/10 Implementasi server $article->views++;
Request pertama:
{
"id": 10,
"views": 101
}
Request kedua:
{
"id": 10,
"views": 102
}
Request ketiga:
{
"id": 10,
"views": 103
}
Disini request yang identik menghasilkan state yang berbeda setiap kali dieksekusi. 100 → 101 → 102 → 103
Perilaku seperti ini tidak lagi bersifat idempotent walaupun menggunakan method PUT atau PATCH. Kenapa Perlu Diperhatikan?
Misalnya terjadi kondisi seperti berikut:
- Client mengirim PATCH /users/1
- Server berhasil memperbarui data
- Server mengirim response
- Koneksi internet terputus
- Client tidak menerima response
- Client menganggap request gagal
- Client melakukan retry
Jika PATCH digunakan untuk mengubah nilai menjadi kondisi tertentu: PATCH /articles/10
Maka retry akan menghasilkan: 100 → 101 ,101 → 102 Padahal aksi yang dimaksud pengguna hanya terjadi satu kali.
PUT dan PATCH umumnya bersifat idempotent karena digunakan untuk mengubah resource ke kondisi tertentu. Mengirim request yang sama berkali-kali akan menghasilkan state akhir yang sama. Namun idempotency tidak ditentukan oleh HTTP Method saja, melainkan juga oleh implementasinya. Jika PUT atau PATCH digunakan untuk operasi seperti penambahan counter, penambahan saldo, atau increment nilai tertentu, maka request yang identik dapat menghasilkan state yang berbeda dan tidak lagi bersifat idempotent.
Implementasi DELETE
Contoh Benar ✅
DELETE digunakan untuk menghapus resource yang sudah ada. Misalnya terdapat data user:
{
"id": 1,
"name": "Budi"
}
Kemudian client mengirim request: DELETE /users/1
Request pertama:
{
"message": "User berhasil dihapus"
}
Data user sekarang sudah tidak ada. Jika request yang sama dikirim kembali:
DELETE /users/1
Maka server dapat memberikan response seperti:
{
"message": "User tidak ditemukan"
}
atau
{
"message": "User sudah dihapus"
}
Walaupun response dapat berbeda, state akhir server tetap sama yaitu user tersebut tidak ada lagi. Inilah yang membuat DELETE bersifat idempotent.
Contoh Salah ❌
Kesalahan yang sering terjadi adalah menambahkan efek samping setiap kali DELETE dipanggil.
Misalnya: DELETE /users/1 Implementasi server: $totalDeleted++ Request pertama:
{
"message": "User berhasil dihapus"
}
Jika request yang sama dikirim kembali: State server: totalDeleted = 2
Lallu jika dikirim kembali ke-3 State server: totalDeleted = 3
Disini request yang identik menghasilkan state yang berbeda setiap kali dieksekusi, 0 → 1 → 2 → 3 Walaupun resource yang dihapus sudah tidak ada, request DELETE tetap memberikan efek samping baru pada server sehingga tidak lagi bersifat idempotent.
Kenapa Perlu Diperhatikan?
Misalnya terjadi kondisi seperti berikut:
- Client mengirim DELETE /users/1
- Server berhasil menghapus user
- Server mengirim response
- Koneksi internet terputus
- Client tidak menerima response
- Client menganggap request gagal
- Client melakukan retry
Jika DELETE diimplementasikan dengan benar:
- Request pertama: User ada → User terhapus
- Retry: User sudah terhapus → Tetap terhapus
State akhir server tetap sama sehingga retry aman dilakukan. Namun jika setiap DELETE juga melakukan proses tambahan seperti:
- $totalDeleted++ / $point -= 10; / $logDelete++;
Maka retry dapat menghasilkan efek samping yang tidak diinginkan walaupun resource sebenarnya sudah terhapus pada request pertama.
DELETE secara alami bersifat idempotent karena tujuan utamanya adalah memastikan suatu resource tidak ada lagi. Mengirim request DELETE yang sama berkali-kali akan menghasilkan state akhir yang sama, yaitu resource tetap terhapus. Namun idempotency tidak hanya ditentukan oleh HTTP Method yang digunakan, melainkan juga oleh implementasinya. Jika DELETE menimbulkan efek samping tambahan setiap kali dieksekusi, maka request yang identik dapat menghasilkan state yang berbeda dan tidak lagi bersifat idempotent.
Stateless

Stateless adalah prinsip RESTful API dimana server tidak menyimpan state atau informasi session yang berkaitan dengan client. Setiap request harus bersifat independen dan membawa seluruh informasi yang dibutuhkan server untuk memprosesnya, sehingga server tidak perlu mengetahui atau mengingat request sebelumnya. Dengan pendekatan ini, client bertanggung jawab mengelola state-nya sendiri, sementara server hanya memproses request berdasarkan data yang diterima pada saat itu.
Keuntungan Stateless RESTful API
-
RESTful API yang stateless akan mudah di scaling secara horizontal, karena request dari client bisa masuk ke server mana saja, sehingga untuk scaling hanya tinggal menambah server baru.
-
Sederhana, karena tidak perlu tahu state sebelumnya yang sangat kompleks.
-
Setiap request client akan sangat lengkap, sehingga mudah untuk di track dan di cek request nya.
RESTful API Documentation
RESTful API tidak memiliki spesifikasi resmi dan ketat seperti SOAP. Karena REST merupakan gaya arsitektur, implementasinya dapat berbeda-beda pada setiap API. Oleh karena itu, untuk memudahkan client dalam memahami dan menggunakan RESTful API yang kita buat, sebaiknya disediakan dokumentasi yang jelas. Dokumentasi dapat dibuat dalam berbagai bentuk, mulai dari dokumen sederhana seperti Microsoft Word atau Google Docs hingga menggunakan tool khusus dokumentasi API.
Untuk API yang digunakan oleh banyak developer, penggunaan tool khusus seperti Swagger/OpenAPI umumnya lebih disarankan karena dapat mendokumentasikan endpoint, parameter, request, response, dan contoh penggunaan secara lebih terstruktur.
Membuat RESTful API
Kesalahan Membuat RESTful API ❌
-
Selalu membuat CRUD API untuk table di database
-
Membuat response data sama dengan table di database
-
Membuat API terlebih dahulu, baru mengerjakan Web atau Mobile menggunakan API yang sudah dibuat
-
Mengembalikan data selengkap-lengkapnya di API
-
Membuat API yang tidak dibutuhkan oleh Client
Tahapan Membuat RESTful API ✅

Contoh :
1.Business Flow
Barang Masuk
↓
Stok Bertambah
↓
Barang Keluar
↓
Stok Berkurang
↓
User Melihat Stok Saat Ini
2. UI/UX Screen

3. API Documentation
Melihat daftar barang GET /api/items
[
{
"id": 1,
"name": "Mouse",
"stock": 25
},
{
"id": 2,
"name": "Keyboard",
"stock": 10
}
]
Detail barang GET /api/items/1
{
"id": 1,
"name": "Mouse",
"stock": 25
}
Barang masuk POST /api/items/1/inbound
{
"qty": 10
}
Response :
{
"message": "Stock updated",
"stock": 35
}
Barang keluar POST /api/items/1/outbound
{
"qty": 5
}
Response :
{
"message": "Stock updated",
"stock": 30
}
4. Develop RESTful API
Implementasikan endpoint sesuai dokumentasi.
Route
GET /api/items
GET /api/items/{id}
POST /api/items/{id}/inbound
POST /api/items/{id}/outbound
Maintenance RESTful API
Dalam membuat produk, fitur pasti akan selalu bertambah, Tak jarang kita mungkin melakukan perubahan di screen Web atau Mobile yang sama. Oleh karena itu, maintenance RESTful API sangatlah penting, agar RESTful API kita tidak menjadi masalah di kemudian hari.
Maintenance : yang Boleh Dilakukan ✅
-
Menambah data baru di API yang sudah ada
-
Menambah API baru di endpoint URL berbeda
-
Mempercepat proses di API yang sudah ada
-
Menggabungkan beberapa API menjadi satu, tanpa menghilangkan API lama
Maintenance : yang tidak Boleh Dilakukan ❌
-
Mengubah total response data di API yang sudah ada
-
Merubah field response data di API yang sudah ada
-
Menghilangkan API yang sudah ada
-
Men-split API yang sudah ada menjadi dua atau lebih
-
Menggabungkan beberapa API menjadi satu dengan menghapus API lama
Maintanance itu simple, jangan break existing API yang sudah di publish.
Implementasi RESTful API menggunakan Laravel.
Padas implementasi kali ini studi kasus yang digunakan adalah RESTful API To do list. alasannya simple tidak terlalu kompleks dan dapat diimplementasikan dengan Full Resource API / CRUD API.
Sebelumnya gue sendiri udah buat, lebih tepat nya copy project dari PZN untuk contoh pengaplikasiannya di Github - Laravel 13 Management Contact RESTful API. Tapi buat memastikan lagi pemahaman lebih matang terkait RESTful API ini jadi gue implementasikan di kasus lain yaitu RESTful API To do list. Seperti sebelumnya implementasi dibagi menajdi 4 bagian.
1. Bisnis Flow
DESKRIPSI
Aplikasi untuk mencatat dan mengelola daftar pekerjaan (todo) dengan autentikasi. Setiap user hanya dapat mengelola todo miliknya sendiri.
AKTOR
- User : Registrasi, login, kelola todo pribadi
ATURAN BISNIS
- Judul todo wajib diisi
- Deskripsi opsional
- Status awal todo: Belum Selesai
- Todo hanya bisa diakses oleh pemiliknya
- User harus login untuk akses todo
- Login via username ATAU email
FLOW
REGISTER: User
- Isi Form (nama, username, email, password)
- Validasi (unique, min 8)
- User Tersimpan
- Login untuk dapat token
LOGIN: User
- Input login (username/email) + password
- Validasi kredensial
- Generate Token (Sanctum)
- Token dikembalikan
LOGOUT: User
- Kirim token
- Token dihapus dari database
- Sesi berakhir
CREATE TODO: User (Auth)
- Isi judul + deskripsi
- Validasi
- Todo tersimpan (status: Belum Selesai)
LIST TODO: User (Auth)
- Minta daftar
- Sistem tampilkan semua todo milik user
- Diurutkan terbaru
DETAIL TODO: User (Auth)
- Pilih todo by ID
- Sistem tampilkan detail
UPDATE TODO: User (Auth)
- Pilih todo
- Edit judul / deskripsi / status
- Validasi
- Simpan
COMPLETE TODO: User (Auth)
- Centang selesai
- is_completed = true
- Todo tertandai selesai
DELETE TODO: User (Auth)
- Pilih todo
- Konfirmasi hapus
- Todo dihapus
2. UI/UX Design
Salah satu acuan pembuatan RESTful API adalah kebutuhan bisnis dan kebutuhan pengguna. UI/UX dapat digunakan sebagai acuan untuk membantu mendefinisikan API yang dibutuhkan. Dalam banyak kasus, praktik yang baik adalah membuat Business Flow terlebih dahulu, kemudian UI/UX, lalu menyusun API Documentation berdasarkan kebutuhan UI/UX tersebut. (dalam kasus ini yang dibuat adalah api spec dulu seharusnya UI/UX, karena project simple, uinya dibuatkan saja oleh oleh AI, fokus ke RESTful API)
Register Form

Login Form

Todo List
3. API Documentation
Dokumentasi API menggunakan OpenAPI karena merupakan salah satu standar yang paling umum digunakan untuk mendeskripsikan REST API. bukan satu-satunya standar, tetapi memang yang paling populer saat ini. Seperti sebelumnya API Documentation itu bebas bisa menggunakan apa saja bahkan Pdf/Word.
Pada artikel ini hanya menampilkan daftar endpoint (Method + URL) yang akan digunakan. Dokumentasi OpenAPI lengkap yang berisi request, response, schema, validasi, dan autentikasi dapat dilihat pada https://github.com/junaedimg/todolist-restfulapi/tree/main/docs.
# User
POST /api/register
POST /api/login
DELETE /api/logout
GET /api/users/current
PATCH /api/users/current
# Todo
GET /api/todos
POST /api/todos
GET /api/todos/{todoId}
PATCH /api/todos/{todoId}
DELETE /api/todos/{todoId}
4. Develop RESTful API
berikut reponya https://github.com/junaedimg/todolist-restfulapi.git. Untuk back end API menggunakan Laravel 13, dengan api route seperti ini.
<?php
use App\Http\Controllers\TodoController;
use App\Http\Controllers\UserController;
use Illuminate\Support\Facades\Route;
Route::post('/register', [UserController::class, 'register']);
Route::post('/login', [UserController::class, 'login']);
Route::middleware('auth:sanctum')->group(function () {
Route::post('/users/logout', [UserController::class, 'logout']);
Route::get('/users/current', [UserController::class, 'current']);
Route::patch('/users/current', [UserController::class, 'update']);
Route::get('/todos', [TodoController::class, 'index']);
Route::post('/todos', [TodoController::class, 'store']);
Route::get('/todos/{id}', [TodoController::class, 'show']);
Route::patch('/todos/{id}', [TodoController::class, 'update']);
Route::delete('/todos/{id}', [TodoController::class, 'destroy']);
});
Learning Notes
- Method PUT dan PATCH itu tidak sesederhana itu untuk dipahami diawal.
dengan contoh table user dengan filed
id
username
password
api_token
inti pemahamannya gunakan PUT ketika mengubah representasi lengkap field yang dapat diubah. misal username dan passwrod karena
-
idtidak dapat diubah.api_tokendikelola server dan tidak dapat diubah oleh user.
gunakan PATCH ketika mengubah salah satu dari username atau password
- Example pada penulisan OpenAPI itu bisa lebih dari 1.
Referensi
PLAYLIST YOUTUBE - REST API (Web Programming Unpas)
PLAYLIST YOUTUBE - REST API (Programmer Zaman Now)
YOUTUBE - Tutorial Laravel RESTful API (Programmer Zaman Now)
https://bif.telkomuniversity.ac.id/apa-itu-api/
https://www.ibm.com/id-id/think/topics/api
https://www.ibm.com/id-id/think/topics/rest-apis
https://idwebhost.com/blog/authentication-vs-authorization/

lfvyfwzoxnrnsmuteltylookhmphhe
yxpotjmwzfpjthdeiugnjrlqjiltoe
psoffwteoxjnhfwztexwnoyojvsjxm