Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Konstruksi lapisan 2
Repositori AWS CDK open sourceaws-cdk-lib
, secara kasar dibagi menjadi satu paket per AWS layanan, meskipun hal ini tidak selalu terjadi. Seperti yang telah dibahas sebelumnya, konstruksi L1 dihasilkan secara otomatis selama proses pembuatan, jadi apa semua kode yang Anda lihat ketika Anda melihat ke dalam repositori? Itu adalah konstruksi L2, yang merupakan abstraksi dari konstruksi L1.
Paket juga berisi kumpulan TypeScript jenis, enum, dan antarmuka serta kelas pembantu yang menambahkan lebih banyak fungsionalitas, tetapi semua item tersebut melayani konstruksi L2. Semua konstruksi L2 memanggil konstruksi L1 yang sesuai dalam konstruktornya setelah instantiasi, dan konstruksi L1 yang dihasilkan yang dibuat dapat diakses dari lapisan 2 seperti ini:
const role = new Bucket(this, "amzn-s3-demo-bucket", {/*...BucketProps*/}); const cfnBucket = role.node.defaultChild;
Konstruksi L2 mengambil properti default, metode kenyamanan, dan gula sintaksis lainnya dan menerapkannya pada konstruksi L1. Ini menghilangkan banyak pengulangan dan verbositas yang diperlukan untuk menyediakan sumber daya secara langsung. CloudFormation
Semua konstruksi L2 membangun konstruksi L1 yang sesuai di bawah tenda. Namun, konstruksi L2 sebenarnya tidak memperluas konstruksi L1. Baik konstruksi L1 dan L2 mewarisi kelas khusus yang disebut Construct. Dalam versi 1 Construct
kelas dibangun ke dalam kit pengembangan, tetapi dalam versi 2 itu adalah paket mandiriConstruct
kelas adalah L1, L2, atau konstruksi L3. Konstruksi L2 memperluas kelas ini secara langsung sedangkan konstruksi L1 memperluas kelas yang disebutCfnResource
, seperti yang ditunjukkan pada tabel berikut.
Pohon warisan L1 |
Pohon warisan L2 |
---|---|
Konstruksi L1 → kelas CfnResource → → kelas abstrak CfnRefElement → → → kelas abstrak CfnElement |
Konstruksi L2 → kelas Membangun |
Jika konstruksi L1 dan L2 mewarisi Construct
kelas, mengapa konstruksi L2 tidak memperpanjang L1 saja? Nah, kelas antara Construct
kelas dan layer 1 mengunci konstruksi L1 di tempat sebagai bayangan cermin dari sumber daya. CloudFormation Mereka berisi metode abstrak (metode yang harus disertakan kelas hilir) seperti_toCloudFormation
, yang memaksa konstruksi untuk secara langsung menampilkan CloudFormation sintaks. Konstruksi L2 melewati kelas-kelas tersebut dan memperluas Construct
kelas secara langsung. Ini memberi mereka fleksibilitas untuk mengabstraksi banyak kode yang diperlukan untuk konstruksi L1 dengan membangunnya secara terpisah di dalam konstruktor mereka.
Bagian sebelumnya menampilkan side-by-side perbandingan bucket S3 dari CloudFormation template dan bucket S3 yang sama yang dirender sebagai konstruksi L1. Perbandingan itu menunjukkan bahwa properti dan sintaks hampir identik, dan konstruksi L1 hanya menyimpan tiga atau empat baris dibandingkan dengan konstruksi. CloudFormation Sekarang mari kita bandingkan konstruksi L1 dengan konstruksi L2 untuk bucket S3 yang sama:
Konstruksi L1 untuk ember S3 |
Konstruksi L2 untuk ember S3 |
---|---|
|
|
Seperti yang Anda lihat, konstruksi L2 kurang dari setengah ukuran konstruksi L1. Konstruksi L2 menggunakan banyak teknik untuk mencapai konsolidasi ini. Beberapa teknik ini berlaku untuk konstruksi L2 tunggal, tetapi yang lain dapat digunakan kembali di beberapa konstruksi sehingga mereka dipisahkan ke dalam kelas mereka sendiri untuk digunakan kembali. Konstruksi L2 mengkonsolidasikan CloudFormation sintaks dalam beberapa cara, seperti yang dibahas di bagian berikut.
Properti default
Cara termudah untuk mengkonsolidasikan kode untuk penyediaan sumber daya adalah dengan mengubah pengaturan properti yang paling umum menjadi default. Mereka AWS CDK memiliki akses ke bahasa pemrograman yang kuat dan CloudFormation tidak, jadi default ini sering bersifat kondisional. Terkadang beberapa baris CloudFormation konfigurasi dapat dihilangkan dari AWS CDK kode karena pengaturan tersebut dapat disimpulkan dari nilai properti lain yang diteruskan ke konstruksi.
Struct, tipe, dan antarmuka
Meskipun AWS CDK tersedia dalam beberapa bahasa pemrograman, itu ditulis secara native di TypeScript, sehingga sistem tipe bahasa digunakan untuk menentukan jenis yang membentuk konstruksi L2. Menyelam jauh ke dalam sistem tipe itu berada di luar cakupan panduan ini; lihat TypeScriptdokumentasitype
menjelaskan jenis data apa yang dimiliki variabel tertentu. Ini bisa berupa data dasar sepertistring
, atau data yang lebih kompleks seperti fileobject
. A TypeScript interface
adalah cara lain untuk mengekspresikan tipe TypeScript objek, dan a struct
adalah nama lain untuk antarmuka.
TypeScript tidak menggunakan istilah struct, tetapi jika Anda melihat di Referensi AWS CDK API, Anda akan melihat bahwa struct sebenarnya hanyalah TypeScript antarmuka lain dalam kode. Referensi API juga mengacu pada antarmuka tertentu sebagai antarmuka juga. Jika struct dan antarmuka adalah hal yang sama, mengapa AWS CDK dokumentasi membuat perbedaan di antara mereka?
Apa yang AWS CDK disebut sebagai struct adalah antarmuka yang mewakili objek apa pun yang digunakan oleh konstruksi L2. Ini termasuk tipe objek untuk argumen properti yang diteruskan ke konstruksi L2 selama instantiasi, seperti BucketProps
untuk konstruksi S3 Bucket dan TableProps
untuk konstruksi DynamoDB Table, serta antarmuka lain yang digunakan dalam. TypeScript AWS CDK Singkatnya, jika itu adalah TypeScript antarmuka di dalam AWS CDK dan namanya tidak diawali dengan hurufI
, itu AWS CDK menyebutnya struct.
Sebaliknya, AWS CDK penggunaan istilah antarmuka untuk mewakili elemen dasar objek biasa perlu dianggap sebagai representasi yang tepat dari konstruksi atau kelas pembantu tertentu. Artinya, antarmuka menjelaskan apa yang harus menjadi properti publik konstruksi L2. Semua nama AWS CDK antarmuka adalah nama konstruksi yang ada atau kelas pembantu yang diawali dengan huruf. I
Semua konstruksi L2 memperluas Construct
kelas, tetapi mereka juga mengimplementasikan antarmuka yang sesuai. Jadi konstruksi L2 Bucket
mengimplementasikan antarmuka. IBucket
Metode statis
Setiap instance konstruksi L2 juga merupakan instance dari antarmuka yang sesuai, tetapi kebalikannya tidak benar. Ini penting ketika melihat melalui struct untuk melihat tipe data mana yang diperlukan. Jika struct memiliki properti yang disebutbucket
, yang memerlukan tipe dataIBucket
, Anda bisa melewatkan objek yang berisi properti yang terdaftar di IBucket
antarmuka atau instance Bucket
L2. Salah satu akan bekerja. Namun, jika bucket
properti itu memanggil L2Bucket
, Anda hanya bisa melewatkan Bucket
instance di bidang itu.
Perbedaan ini menjadi sangat penting ketika Anda mengimpor sumber daya yang sudah ada sebelumnya ke tumpukan Anda. Anda dapat membuat konstruksi L2 untuk sumber daya apa pun yang asli dari tumpukan Anda, tetapi jika Anda perlu mereferensikan sumber daya yang dibuat di luar tumpukan, Anda harus menggunakan antarmuka konstruksi L2 itu. Itu karena membuat konstruksi L2 menciptakan sumber daya baru jika belum ada di dalam tumpukan itu. Referensi ke sumber daya yang ada harus berupa objek biasa yang sesuai dengan antarmuka konstruksi L2 itu.
Untuk membuatnya lebih mudah dalam praktiknya, sebagian besar konstruksi L2 memiliki seperangkat metode statis yang terkait dengannya yang mengembalikan antarmuka konstruksi L2 itu. Metode statis ini biasanya dimulai dengan katafrom
. Dua argumen pertama yang diteruskan ke metode ini adalah sama scope
dan id
argumen yang diperlukan untuk konstruksi L2 standar. Namun, argumen ketiga tidak props
hanya sebagian kecil dari properti (atau kadang-kadang hanya satu properti) yang mendefinisikan antarmuka. Untuk alasan ini, ketika Anda melewati konstruksi L2, dalam banyak kasus hanya elemen antarmuka yang diperlukan. Ini agar Anda dapat menggunakan sumber daya yang diimpor juga, jika memungkinkan.
// Example of referencing an external S3 bucket const preExistingBucket = Bucket.fromBucketName(this, "external-bucket", "name-of-bucket-that-already-exists");
Namun, Anda tidak harus terlalu bergantung pada antarmuka. Anda harus mengimpor sumber daya dan menggunakan antarmuka secara langsung hanya jika benar-benar diperlukan, karena antarmuka tidak menyediakan banyak properti — seperti metode pembantu — yang membuat konstruksi L2 begitu kuat.
Metode pembantu
Konstruksi L2 adalah kelas terprogram daripada objek sederhana, sehingga dapat mengekspos metode kelas yang memungkinkan Anda untuk memanipulasi konfigurasi sumber daya Anda setelah instantiasi telah terjadi. Contoh yang baik dari ini adalah konstruksi Peran L2 AWS Identity and Access Management (IAM). Cuplikan berikut menunjukkan dua cara untuk membuat peran IAM yang sama dengan menggunakan konstruksi L2. Role
Tanpa metode pembantu:
const role = new Role(this, "my-iam-role", { assumedBy: new FederatedPrincipal('my-identity-provider.com'), managedPolicies: [ ManagedPolicy.fromAwsManagedPolicyName("ReadOnlyAccess") ], inlinePolicies: { lambdaPolicy: new PolicyDocument({ statements: [ new PolicyStatement({ effect: Effect.ALLOW, actions: [ 'lambda:UpdateFunctionCode' ], resources: [ 'arn:aws:lambda:us-east-1:123456789012:function:my-function' ] }) ] }) } });
Dengan metode pembantu:
const role = new Role(this, "my-iam-role", { assumedBy: new FederatedPrincipal('my-identity-provider.com') }); role.addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName("ReadOnlyAccess")); role.attachInlinePolicy(new Policy(this, "lambda-policy", { policyName: "lambdaPolicy", statements: [ new PolicyStatement({ effect: Effect.ALLOW, actions: [ 'lambda:UpdateFunctionCode' ], resources: [ 'arn:aws:lambda:us-east-1:123456789012:function:my-function' ] }) ] }));
Kemampuan untuk menggunakan metode instance untuk memanipulasi konfigurasi sumber daya setelah instantiation memberikan konstruksi L2 banyak fleksibilitas tambahan atas lapisan sebelumnya. Konstruksi L1 juga mewarisi beberapa metode sumber daya (sepertiaddPropertyOverride
), tetapi tidak sampai lapisan dua Anda mendapatkan metode yang dirancang khusus untuk sumber daya itu dan propertinya.
Enum
CloudFormation sintaks sering mengharuskan Anda untuk menentukan banyak detail untuk menyediakan sumber daya dengan benar. Namun, sebagian besar kasus penggunaan sering kali hanya tercakup oleh segelintir konfigurasi. Mewakili konfigurasi tersebut dengan menggunakan serangkaian nilai yang disebutkan dapat sangat mengurangi jumlah kode yang dibutuhkan.
Misalnya, dalam contoh kode L2 bucket S3 dari sebelumnya di bagian ini, Anda harus menggunakan bucketEncryption
properti CloudFormation template untuk memberikan semua detail, termasuk nama algoritma enkripsi yang akan digunakan. Sebagai gantinya, AWS CDK
menyediakan BucketEncryption
enum, yang mengambil lima bentuk enkripsi bucket yang paling umum dan memungkinkan Anda mengekspresikan masing-masing dengan menggunakan nama variabel tunggal.
Bagaimana dengan kasus tepi yang tidak tercakup oleh enum? Salah satu tujuan dari konstruksi L2 adalah untuk menyederhanakan tugas penyediaan sumber daya lapisan 1, sehingga kasus tepi tertentu yang kurang umum digunakan mungkin tidak didukung di lapisan 2. Untuk mendukung kasus tepi ini, AWS CDK memungkinkan Anda memanipulasi properti CloudFormation sumber daya yang mendasarinya secara langsung dengan menggunakan addPropertyOverridemetode ini. Untuk informasi selengkapnya tentang penggantian properti, lihat bagian Praktik terbaik dari panduan ini dan bagian Abstraksi dan lubang keluar dalam dokumentasi. AWS CDK
Kelas pembantu
Terkadang enum tidak dapat menyelesaikan logika terprogram yang diperlukan untuk mengonfigurasi sumber daya untuk kasus penggunaan tertentu. Dalam situasi ini, AWS CDK sering menawarkan kelas pembantu sebagai gantinya. Enum adalah objek sederhana yang menawarkan serangkaian pasangan kunci-nilai, sedangkan kelas pembantu menawarkan kemampuan penuh kelas. TypeScript Kelas pembantu masih dapat bertindak seperti enum dengan mengekspos properti statis, tetapi properti tersebut kemudian dapat menetapkan nilainya secara internal dengan logika bersyarat di konstruktor kelas pembantu atau dalam metode pembantu.
Jadi meskipun BucketEncryption
enum dapat mengurangi jumlah kode yang diperlukan untuk mengatur algoritme enkripsi pada bucket S3, strategi yang sama tidak akan berfungsi untuk mengatur durasi waktu karena ada terlalu banyak nilai yang mungkin untuk dipilih. Membuat enum untuk setiap nilai akan jauh lebih merepotkan daripada nilainya. Untuk alasan ini, kelas helper digunakan untuk pengaturan konfigurasi Kunci Objek S3 bucket default S3, seperti yang diwakili oleh kelas. ObjectLockRetention ObjectLockRetention
berisi dua metode statis: satu untuk retensi kepatuhan dan yang lainnya untuk retensi tata kelola. Kedua metode mengambil contoh dari kelas pembantu Durasi sebagai argumen untuk menyatakan jumlah waktu yang harus dikonfigurasi kunci.
Contoh lain adalah Runtime kelas AWS Lambda pembantu. Pada pandangan pertama, mungkin tampak bahwa properti statis yang terkait dengan kelas ini dapat ditangani oleh enum. Namun, di bawah tenda, setiap nilai properti mewakili instance dari Runtime
kelas itu sendiri, sehingga logika yang dilakukan dalam konstruktor kelas tidak dapat dicapai dalam enum.