Biasanya Anda bisa menemukan saat API pipeline mulai berbohong kepada tim. Sebuah schema berubah, tipe yang dihasilkan diperbarui tanpa keluhan, PR berwarna hijau, dan kemudian seseorang di frontend terus membaca bentuk respons lama karena wrapper menghilangkan kesalahan. Itu adalah masalah OpenAPI TypeScript, bukan apakah generator dapat mengeluarkan interface.
Pertanyaan yang lebih berguna adalah lebih sulit. Apa kontrak yang Anda inginkan antara schema, transport, dan validasi, dan bagian mana yang harus gagal cepat pada waktu build daripada bocor ke waktu eksekusi? Setelah Anda membentuk OpenAPI TypeScript sebagai pilihan pipa, kekurangan menjadi lebih jelas, dan alat-alat berhenti berpura-pura menjadi solusi utuh.
Daftar Isi
- Mengapa Tipe yang Dibuat Tidak Sama dengan API yang Aman
- Menghasilkan Tipe TypeScript dari Spesifikasi OpenAPI
- Memilih Antara Tipe Murni, Klien Penuh, dan Tanpa Pengkodean
- Menghubungkan Klien Tipis yang Dibungkus dengan Fetch atau Axios
- Menambahkan Validasi Waktu Eksekusi dengan zod, ajv, atau io-ts
- Mengatur Pengujian Generasi, Validasi, dan Kontrak di CI
- Mengelola Pipa yang Dapat Dibangun Kembali, Kinerja, dan Checklist Akhir
Mengapa Tipe-Tipe yang Dibuat Tidak Sama dengan API yang Aman
Seorang rekan tim menggabungkan PR yang menambahkan bidang respons opsional. File yang dibuat secara otomatis diperbarui dengan bersih, perbedaan kode tampaknya tidak menarik, dan semua orang melanjutkan. Kemudian frontend terus membaca bentuk yang lebih tua melalui wrapper yang ditulis tangan yang “sementara” ditetapkan dengan as anydan produksi mulai berperilaku seperti kontrak tidak pernah berubah.
Itu adalah perangkap dengan tipe-tipe yang dibuat. TypeScript hanya dapat melindungi code yang mengonsumsi tipe-tipe yang dibuat, dan hanya jika lapisan transportasi tidak menghapus kontrak lagi. Sisi OpenAPI memberikan skema, bukan jaminan bahwa setiap pengguna menghormatinya. Diskusi seputar memahami __CAPGO_KEEP_0__ yang terhubung discussion around understanding API connections bermanfaat di sini karena memindahkan percakapan dari alat tunggal menuju bagaimana sistem terhubung.
Dimana kegagalan disembunyikan
Poin pemisah paling umum adalah membosankan, bukan eksotis. Drift skema terjadi ketika spesifikasi OpenAPI dan layanan yang dijalankan tidak lagi sejalan. Koverasi parsial muncul ketika spesifikasi hanya menggambarkan jalur bahagia, sementara aplikasi bergantung pada kasus pinggir yang tidak terdokumentasikan. Penggunaan wrapper tangan sering kali di mana tipe menjadi lemah, terutama ketika seseorang ingin “bergerak cepat” dan menggunakan any atau cast respons yang longgar.
Aturan praktis: jika wrapper dapat berbohong, generator tidak dapat menyelamatkan Anda.
Ada juga celah waktu eksekusi. Tipe TypeScript hilang setelah kompilasi, sehingga mereka tidak dapat menolak JSON yang rusak yang datang melalui kabel. Jaringan tidak peduli apa yang disarankan editor Anda, dan itu mengapa klien yang dihasilkan hanya satu lapisan dalam pipa yang lebih aman API.
Kuesioner operasional yang lebih luas adalah keamanan dan disiplin kontrak, bukan hanya kemudahan pengembang. Jika Anda ingin tampilan struktur tentang bagaimana API kontrak masuk ke dalam siklus hidup aplikasi yang lebih besar, panduan internal ini tentang API standar keamanan untuk kinerja aplikasi di toko aplikasi API security standards for app store compliance Cara yang lebih dewasa untuk berpikir tentang openapi typescript adalah ini. Ini memberikan jembatan schema-to-types yang ketat, yang sangat baik, tetapi tidak memvalidasi permintaan, menerapkan bentuk payload waktu eksekusi, atau menghentikan wrapper yang tidak teliti dari merusak segalanya. Generator adalah 20 persen yang mudah. Sisanya adalah desain pipa, dan itu di mana tim-tim mendapatkan kepercayaan atau mengumpulkan kepercayaan palsu.
Menghasilkan Tipe TypeScript dari Spesifikasi OpenAPI Screenshot dari https://openapi-ts.dev Konfigurasi yang paling ringan dan berguna biasanya adalah yang yang bertahan dalam perubahan repo yang nyata. Simpan spesifikasi OpenAPI di repositori yang sama, hasilkan file tipe yang dikomit, dan buat perubahan yang hilang terlihat di CI bukan bergantung pada seseorang untuk mengingat langkah refresh. Perintah seperti
memberikan Anda file output yang deterministik yang dapat diperiksa oleh reviewer seperti perubahan sumber lainnya.

__CAPGO_KEEP_0__ npx openapi-typescript ./openapi.yaml -o ./src/types/api.d.ts __CAPGO_KEEP_0__
__CAPGO_KEEP_0__
The -o flag keluaran sangat penting karena membuat artefak yang dihasilkan menjadi eksplisit. --immutable berguna ketika Anda ingin jenis yang dihasilkan mempertahankan tujuan readonly di keluaran, dan --alphabetize menggunakan perbedaan stabil ketika urutan skema berubah tanpa makna semantik. --enum penting ketika tim Anda lebih suka enum di permukaan yang dihasilkan daripada union.
Dokumentasi proyek sendiri jelas tentang ruang lingkup, itu adalah penghasil jenis, bukan runtime klien atau lapisan permintaan, dan batasan tersebut membantu ketika Anda ingin setup yang ringan, jenis pertama. Repositorinya juga menunjukkan model perawatan di balik alat, yang merupakan bagian dari mengapa perangkat lunak terbuka dapat bertahan di produksi ketika dokumen dan rilis tetap aktif, seperti yang dibahas dalamkasus untuk perawatan terbuka GitHub repository and CLI documentation.
__CAPGO_KEEP_0__ dan dokumentasi __CAPGO_KEEP_1__ package.json Jadi perintah ini berada di samping skrip build lainnya, lalu jalankan ketika spesifikasi berubah. Di CI, regenerasi file dan gagal jika git diff Menggambarkan perubahan kontrak menjadi pekerjaan tinjauan yang terlihat bukan risiko runtime yang diam.
Di sisi schema berlaku sebanding dengan perintah baris perintah. Projek merekomendasikan compilerOptions.noUncheckedIndexedAccess Jadi additionalProperties menjadi T | undefined, yang memaksa indexing yang lebih aman di situs panggilan. Projek juga merekomendasikan menggunakan oneOf sendiri daripada mencampurnya dengan komposisi tambahan, dan menjaga $defs di root ketika penempatan ambigu, karena definisi yang salah dapat hilang dari output yang dihasilkan. Detail tambahan satu ini menyelamatkan waktu nanti, openapi-typescript tidak akan menghasilkan any, sehingga detail schema yang hilang dapat muncul lebih awal bukan disembunyikan di bawah jenis yang permissive.
Tetapkan spesifikasi secara eksplisit, atau generator akan setia menampilkan ketidakpastian kembali ke Anda.
Alur kerja yang bertahan adalah sederhana. Letakkan spesifikasi di bawah pengawasan versi, regenerasi pada build, komit file yang dihasilkan, dan biarkan checker jenis mengeluh sebelum siapa pun menggabungkan kesalahan yang tidak sesuai. Ini memberikan batasan kontrak yang stabil untuk sisa pipa.
Memilih Antara Tipe Murni, Klien Penuh, dan Tanpa Pengkodean Kode
| Polanya | Waktu Pembangunan | File Keluaran | Berat Paket | Pilihan Terbaik |
|---|---|---|---|---|
| Tipe Murni dengan Pelapis Tipis | Cepat | Sedikit | Rendah | Tim yang Ingin Mengontrol dan Permukaan Runtime yang Kecil |
| Pengkodean Klien Penuh | Lebih Lambat | Banyak | Lebih Tinggi | Tim yang ingin handoff cepat dan operasi yang dihasilkan secara otomatis |
| Tidak ada pembuat permintaan codegen | Cepat | Tidak ada atau minimal | Rendah | Aplikasi dengan kode tunggal yang lebih suka logika transportasi yang ditulis tangan |
Pilihan bukanlah “alat mana yang menang”. Itu adalah bentuk pipa yang mana yang sesuai dengan repositori Anda, tim Anda, dan berapa banyak perubahan yang dilihat oleh API. Dalam benchmark tahun 2025 sekitar spesifikasi OpenAPI besar sekitar 75.000 baris, 2 MB, dan sekitar 1.200 operasi, openapi-typescript output yang dihasilkan sekitar 1,5 detik dibandingkan dengan sekitar 8,0 detik untuk @hey-api/openapi-ts, 5,5 detik untuk Orval, dan 18,1 detik untuk Kubb, sambil juga menghasilkan satu file output tunggal versus 16 untuk hey-api, 2,719 untuk Orvaldan 3,877 untuk Kubb (detail benchmark).
Tipe murni lebih mengutamakan kontrol
Konfigurasi tipe murni cocok dengan layer permintaan yang ditulis tangan karena Anda dapat menjaga ukuran runtime kecil dan permukaan API membosankan. Hal ini penting di front-end yang sensitif bundler dan di aplikasi di mana satu tim mengelola spesifikasi dan konsumen. Jika Anda perlu diingatkan bahwa pengalaman pengembang bukan hanya gula sintaks, maka pengalaman pengembang sudut lebih mudah dihakimi ketika klien code pendek, jelas, dan dapat direview.
Pelanggan penuh mengutamakan kecepatan handoff
openapi-generator, hey-api, Orval, dan Kubb semua mencoba melakukan lebih dari tipe. Hal ini dapat membantu ketika Anda ingin metode permintaan, model, dan pipa yang dihasilkan bersamaan, terutama dalam handoff besar antara tim backend dan frontend. Biaya yang jelas terlihat dalam benchmark di atas, yaitu file yang dihasilkan lebih banyak, permukaan runtime yang lebih besar, dan lebih banyak ruang untuk gesekan build ketika spesifikasi tumbuh.
Tidak ada penggunaan kode favorit refaktor lokal
Pembuat permintaan yang ditipe dan fetch Pita pengguna berfungsi dengan baik ketika satu basis kode menguasai kedua ujung bentuk dan perubahan API disinkronkan dengan ketat. Namun, kelemahan adalah disiplin perawatan. Semakin banyak tim dan repositori yang berada di antara produsen dan konsumen, semakin mungkin layer permintaan yang ditulis tangan mengalami perubahan kecuali Anda menegakkan tes kontrak secara agresif.
Poin keputusan inti bukanlah ideologi. Jika anggaran bundel Anda terbatas, tipe murni menarik. Jika tim Anda ingin maksimal scaffolding dan dapat menyerap output, klien penuh mengurangi waktu pengaturan. Jika Anda ingin bagian yang paling sedikit bergerak dan dapat menjaga kontrak dekat, pembuat permintaan tanpa kodegen dapat menjadi pilihan internal yang tepat.
Memasang Klien Tipis yang Tipe Tipis Menggunakan Fetch atau Axios

Pita pengguna tipis adalah di mana generator berhenti dan aplikasi code Anda dimulai. Pembungkus harus menampilkan satu fungsi per operasi, menerima parameter dan objek kueri yang ditipekan, dan mengirimkan panggilan ke fetch atau instance yang diinjeksi axios tanpa mencoba menjadi pintar. Dalam sebagian besar pengaturan produksi, lapisan ini tetap ada 30–60 baris karena jenis yang dibuat sudah membawa bentuk sebagian besar.
Ini adalah model mental yang tetap berlaku:
- Parameter jalur tetap ditipekan sehingga
/users/{id}tidak bisa disebut tanpa __CAPGO_KEEP_0__id. - Objek Query tetap berjenis jadi filter opsional tidak berubah menjadi sup kacang.
- Badan Respon tetap berjenis jadi parsing code dapat percaya bentuk sempit yang diharapkan.
Wrapper seperti itu sengaja membosankan. Tidak harus menciptakan ulang retries, transforms, atau kebijakan autentikasi jika itu milik tempat lain. Tidak harus mengubah permintaan dari operasi berjenis ke lapisan transportasi dan kemudian mengembalikan hasil berjenis ke atas.
Tahanlah wrapper membosankan dan ringan ketergantungan, atau setiap perubahan kodegen masa depan akan berdampak pada aplikasi Anda.
Gagal umumnya adalah memperbaiki kesalahan dengan as any ketika jenis yang dihasilkan tidak sesuai dengan tanda tangan wrapper lama. Ini membeli bangunan hijau dan aplikasi yang rapuh. Ini juga menyembunyikan kontrak perubahan yang Anda inginkan generator untuk mengekspos.
Untuk tim yang lebih suka Axios, pola yang sama, hanya implementasi transportasi yang berubah. Untuk tim yang ingin code sederhana di sisi browser, fetch cukup sering.
Bagian penting adalah fungsi permintaan menerima jenis jalur yang dihasilkan dan mengembalikan respon berjenis, bukan objek yang longgar yang kemudian diproses lebih lanjut. openapi typescript memberikan Anda pembagian kerja yang bersih. Schema hidup di spesifikasi, transport hidup di pembungkus, dan aplikasi melihat operasi yang ditipekan daripada permintaan ad hoc code.
Tambahan Validasi Runtime dengan zod, ajv, atau io-ts
Jenis data TypeScript menghilang pada runtime, dan jaringan tidak peduli dengan kepercayaan editor Anda. Itulah mengapa pola aman bukanlah 'generate jenis dan harap', tetapi 'generate jenis, lalu validasi di tepi tempat data tidak terpercaya memasuki aplikasi'. Schema yang dihasilkan tetap menjadi sumber kebenaran, dan library validasi seperti zod, ajv, dan io-ts menangani periksa batas yang tidak dapat dilakukan oleh jenis compile-time.
Validasi di tempat data memasuki
Untuk aplikasi React, tepi biasanya tepat setelah permintaan diselesaikan dan sebelum payload memasuki state. Untuk server, itu sebelum payload ditulis ke dalam database atau diserahkan ke aturan bisnis. Aturan sederhana, jaga validasi dekat dengan batas dan jangan menyebarkan periksa manual melalui fitur code.
A zod bentuk dapat mengacu bentuk respons yang dihasilkan tanpa menggantinya:
import { z } from "zod";
const WeatherForecastSchema = z.object({
date: z.string(),
temperatureC: z.number(),
summary: z.string().nullable(),
temperatureF: z.number().optional(),
});
Contoh tersebut memvalidasi bidang yang schema tandai sebagai opsional, dan menjaga periksa runtime sejalan dengan apa yang diproduksi oleh generator. ajv adalah pilihan kuat ketika Anda ingin validasi JSON Schema dengan tingkat arus tinggi pada server, sementara io-ts masih sesuai dengan tim yang sudah hidup di fp-ts gaya komposisi.
kesalahan besar adalah memvalidasi terlambat. Jika payload melintasi ke aplikasi Anda terlebih dahulu, sistem tipe sudah dihindari dan bug memiliki tempat untuk bersembunyi. Panduan singkat tentang unit tests untuk JavaScript cocok dengan mindset ini, karena baik unit tests dan validasi batas berfungsi terbaik ketika menangkap asumsi buruk pada awalnya.
layering yang bersih adalah prediktif. OpenAPI TypeScript menghasilkan kontrak, validator memeriksa payload waktu eksekusi, dan aplikasi Anda code hanya melihat data yang bertahan dari kedua langkah tersebut. Itu adalah batasan yang lebih baik daripada mengandalkan tipe statis untuk memantau respons yang tidak dipercaya.
Menempatkan Pengembangan, Validasi, dan Uji Kontrak di CI

Pipeline yang berlangsung mengubah kontrak menjadi pintu, bukan saran. Regenerasi tipe, gagal pada drift, jalankan tsc --noEmit, dan latih bentuk API terhadap mock atau alat kontrak sebelum merge. Jika Anda memasang versi generator di package.jsondua insinyur tidak dapat secara tidak sengaja menghasilkan hasil yang berbeda dari spesifikasi yang sama.
Aksi bentuk sederhana GitHub
Alur kerja yang praktis seperti ini:
- Pilih spesifikasi dari repositori atau sumber yang dihasilkan.
- Regenerasi jenis.
- Gagalkan pekerjaan jika
git diffmenunjukkan perubahan. - Jalankan
tsc --noEmit. - Eksekusi tes kontrak terhadap mock server seperti Prism atau cek yang didukung Spectral.
Perbedaan utama antara tes kontrak dan tes snapshot adalah ruang lingkup. Tes snapshot seringkali memberitahu Anda bahwa file yang berubah. Tes kontrak memberitahu Anda apakah bentuk masih berperilaku seperti spesifikasi yang mengatakan bahwa harusnya.
Mock server sangat berguna ketika pekerjaan backend dan frontend dipisahkan oleh waktu atau batasan tim. Ini memberikan konsumen code permukaan yang dapat diprediksi API sementara masih memeriksa kontrak yang sebenarnya bukanlah fixture yang dikodekan secara keras. Petunjuk pengaturan integrasi terus menerus jika tim Anda masih membutuhkan basis CI yang bersih dan dapat diulang, maka ini adalah referensi yang berguna.
Mengunci versi generator menghindari salah satu kegagalan yang paling menyakitkan dalam pipeline codegen, yaitu ketidaksesuaian output yang tidak terlihat. Jika salah satu pengembang mengupgrade generator secara lokal dan yang lain tidak, maka file yang dihasilkan dapat menjadi sumber kebisingan acak bukanlah signal. CI harus membuat hal itu tidak mungkin.
Hasilnya adalah pipeline di mana perubahan schema, penghasilan jenis, pengecekan kompiler, dan uji kontrak semua saling memperkuat. Itulah yang membuat alur kerja menjadi jujur.
Pengelolaan Pipa yang Dapat Dibangun, Kinerja, dan Checklist Akhir

Pipa yang bertahan adalah yang memiliki pengelolaan yang membosankan. Versi spesifikasi, tinjau perubahan schema seperti code, kunci generator, dan dokumentasikan bagaimana perubahan yang memecahkan proses mendapatkan persetujuan. Jika prosesnya kabur, maka orang akan mengelilinginya, dan kemudian jenis yang dihasilkan menjadi dekorasi bukanlah penegak.
Beberapa pengaturan kinerja yang sebenarnya berpengaruh
Penghasilan yang dapat ditingkatkan membantu di monorepos di mana spesifikasi berubah sering tetapi hanya satu paket yang menggunakannya. tsc --incremental dapat menghilangkan pekerjaan kompiler yang diulang, dan mengaktifkan flag output yang tidak perlu dalam pembangunan produksi membuat permukaan yang dihasilkan lebih kecil. Dalam prakteknya, kemenangan terbesar masih bersifat sosial, bukan teknis, karena pipa yang dapat diprediksi lebih sering dijalankan daripada pipa yang pintar.
Daftar checklist di bawah ini adalah satu yang patut Anda simpan dekat.
- Penguncian versi: Lepaskan versi generator dan kunci generator untuk versi yang Anda gunakan.
openapi-typescriptversi di dalampackage.jsonjadi output tidak bergeser ke mesin lain. - Ulasan skema: Tangani perubahan spesifikasi sebagai perubahan kontrak yang dapat diulas, bukan perawatan.
- Pengenalan pergeseran: Regenerasi di CI dan gagal jika ada perbedaan.
- Validasi tepi: Parse payload tidak terpercaya sebelum mencapai keadaan aplikasi atau penyimpanan.
- Pengujian kontrak: Lakukan cek yang dibalutkan untuk membuktikan bahwa konsumen code masih sesuai dengan skema.
- Kebijakan perubahan besar: Tuliskan siapa yang menyetujui perubahan bentuk dan bagaimana klien diinformasikan.
Sebuah pipa yang mencakup pintu gerbang tidak hanya menghasilkan jenis, tetapi juga membuat kontrak terlihat. Keterlihatan ini adalah apa yang mencegah tim percaya pada file yang hanya terlihat aman.
Jika Anda mengirimkan aplikasi Capacitor atau Electron dan Anda ingin pipeline pembaruan Anda berperilaku dengan disiplin yang sama, Capgo memberikan cara yang praktis untuk memindahkan perbaikan JavaScript, CSS, salinan, konfigurasi, dan aset tanpa harus menunggu tinjauan toko aplikasi. Capgo __CAPGO_KEEP_0__