Alternatif JSONPlaceholder yang benar-benar menyimpan penulisan
Jenis resource yang sama, tetapi penulisan disimpan, input buruk ditolak, dan error tersedia kapan pun dibutuhkan.
Contoh terakhir dijalankan terhadap API pada
JSONPlaceholder hanya pura-pura menulis: POST mengembalikan id: 101, tetapi GET untuk id itu mengembalikan 404, dan DELETE membiarkan datanya tetap ada. Jika aplikasi Anda perlu membaca kembali apa yang baru ditulisnya, pakai https://api.testingapis.com/apimasuk untuk melihat. Jenis resource-nya sama (post, komentar, album, foto, todo, dan pengguna), dan membuat, mengubah, serta menghapus benar-benar disimpan. API ini juga menolak input yang tidak valid dengan 400 dan bisa membuat request apa pun gagal sesuai permintaan, jadi Anda bisa membangun dan menguji status error juga. Gratis, tanpa key, dan menerima request dari origin mana pun.
Penulisan yang benar-benar disimpan
Inilah yang dilakukan JSONPlaceholder pada post baru:
$ curl -X POST https://jsonplaceholder.typicode.com/posts \
-H "Content-Type: application/json" \
-d '{"title":"hello","body":"world","userId":1}'
{ "title": "hello", "body": "world", "userId": 1, "id": 101 }
$ curl -i https://jsonplaceholder.typicode.com/posts/101
HTTP/1.1 404 Not FoundLangkah yang sama di sini: buat post, baca kembali, edit, hapus, lalu pastikan sudah hilang.
$ curl -X POST https://api.testingapis.com/api/Posts \
-H "Content-Type: application/json" \
-d '{"userId":101,"title":"Hello from the guide","body":"Checking that writes persist."}'
{"message":"Post created successfully","data":{"id":16,"userId":101,"title":"Hello from the guide","body":"Checking that writes persist.","tags":[],"publishedAt":"2026-10-07T02:58:58Z","likes":0}}
$ curl https://api.testingapis.com/api/Posts/16
{"id":16,"userId":101,"title":"Hello from the guide","body":"Checking that writes persist.","tags":[],"publishedAt":"2026-10-07T02:58:58Z","likes":0}
$ curl -X PUT https://api.testingapis.com/api/Posts/16 \
-H "Content-Type: application/json" \
-d '{"userId":101,"title":"Edited title","body":"Checking that writes persist."}'
{"message":"Post updated successfully","data":{"id":16,"userId":101,"title":"Edited title",...}}
$ curl -X DELETE https://api.testingapis.com/api/Posts/16
{"message":"Post deleted successfully"}
$ curl -i https://api.testingapis.com/api/Posts/16
HTTP/1.1 404 Not Found
{"status":404,"error":"Not Found","message":"Post with ID 16 does not exist."}Pemetaan rute
| JSONPlaceholder | testingapis.com | Data |
|---|---|---|
/posts | /api/posts | 15 (JSONPlaceholder: 100) |
/posts/1/comments | /api/posts/1/comments | Komentar pada post 1 |
/comments | /api/commentsdocs | 50 (500) |
/albums | /api/albumsdocs | 10 (100) |
/albums/1/photos | /api/albums/1/photosmasuk untuk melihat | 5 per album |
/photos | /api/photosdocs | 50 (5.000) |
/todos | /api/todos | 30 (200) |
/users | /api/peopledocs | 20 (10), dengan alamat, koordinat, dan perusahaan |
/users/1/posts | /api/posts/user/101 | Id pengguna dimulai dari 101 |
Path tidak peka huruf besar-kecil: /api/posts dan /api/Posts sama saja. Jumlah datanya lebih sedikit daripada JSONPlaceholder, tetapi setiap data punya lebih banyak field. Post punya tag, like, dan tanggal terbit, todo punya prioritas dan tenggat, dan orang punya alamat serta perusahaan bersarang. Dokumentasi API mendaftar 13 jenis resource lagi, dari produk dan keranjang sampai buku, film, dan negara.
/api/posts/1Input buruk mendapat error
JSONPlaceholder menerima body apa pun, bahkan yang kosong. Di sini, field wajib yang hilang mengembalikan 400 dengan pesan, sehingga cabang error di formulir Anda punya sesuatu yang nyata untuk ditampilkan:
$ curl -i -X POST https://jsonplaceholder.typicode.com/posts -H "Content-Type: application/json" -d '{}'
HTTP/1.1 201 Created
{ "id": 101 }
$ curl -i -X POST https://api.testingapis.com/api/Posts -H "Content-Type: application/json" -d '{"title":""}'
HTTP/1.1 400 Bad Request
{"status":400,"error":"Bad Request","message":"Missing required field: title"}Error dan response lambat sesuai permintaan
Tambahkan ?error=500 ke request apa pun agar gagal dengan status itu, atau ?delay=3 agar menjawab tiga detik lebih lambat. Bersama-sama, ?delay=2&error=503 menampilkan status memuat lalu error. Panduan response error membahas timeout, retry, dan rate limit.
/api/todos/1?error=503Filter, pengurutan, dan paginasi
Kedua API memfilter daftar berdasarkan field, seperti ?userId=101, dan keduanya bisa mengurutkan, mencari, dan membagi halaman. Nama parameternya berbeda:
| JSONPlaceholder | testingapis.com | |
|---|---|---|
| Filter | ?userId=1 | ?userId=101 |
| Halaman | ?_page=2&_limit=10 | ?page=2&limit=10 |
| Urutan | ?_sort=id&_order=desc | ?sort=id&order=desc |
| Pencarian | ?q=word | ?q=word |
| Jumlah total | X-Total-Count | X-Total-Count, X-Total-Pages |
Memindahkan aplikasi
Pembacaan mengembalikan data secara langsung, seperti JSONPlaceholder. Penulisan membungkusnya dengan pesan, sebagai { message, data }, dan id pengguna dimulai dari 101. Itulah dua perubahan yang dibutuhkan sebagian besar aplikasi:
// Before
const BASE = "https://jsonplaceholder.typicode.com";
const post = await (await fetch(`${BASE}/posts/1`)).json();
const created = await (await fetch(`${BASE}/posts`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ userId: 1, title: "Hi", body: "There" }),
})).json();
// After
const BASE = "https://api.testingapis.com/api";
const post = await (await fetch(`${BASE}/posts/1`)).json();
const { data: created } = await (await fetch(`${BASE}/posts`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ userId: 101, title: "Hi", body: "There" }),
})).json();Kapan JSONPlaceholder pilihan yang lebih baik
- Anda butuh daftar besar, seperti 5.000 foto untuk menguji virtual scrolling.
- Anda mengikuti tutorial yang memakai id dan field JSONPlaceholder persis.
- Anda hanya membaca data dan tidak pernah butuh penulisan muncul sesudahnya.
Untuk melangkah lebih jauh, pelajaran pengujian CRUD membahas cara memeriksa bahwa setiap pembuatan, perubahan, dan penghapusan benar-benar terjadi.