committed by
GitHub
1 changed files with 258 additions and 0 deletions
@ -0,0 +1,258 @@ |
|||||
|
# Parameter Path |
||||
|
|
||||
|
"parameter" atau "variabel" path didefinisikan dengan sintaksis Python format string: |
||||
|
|
||||
|
{* ../../docs_src/path_params/tutorial001.py hl[6:7] *} |
||||
|
|
||||
|
Nilai parameter path `item_id` akan dikirim ke fungsi sebagai argument `item_id`: |
||||
|
|
||||
|
Jika anda menjalankan contoh berikut dan kunjungi <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, anda akan melihat respon: |
||||
|
|
||||
|
```JSON |
||||
|
{"item_id":"foo"} |
||||
|
``` |
||||
|
|
||||
|
## Parameter path dengan tipe data |
||||
|
|
||||
|
Tipe data parameter path bisa didefinisikan di dalam fungsi, menggunakan anotasi tipe data standar Python: |
||||
|
|
||||
|
{* ../../docs_src/path_params/tutorial002.py hl[7] *} |
||||
|
|
||||
|
Dalam hal ini `item_id` didefinisikan sebagai `int`. |
||||
|
|
||||
|
/// check | Periksa |
||||
|
|
||||
|
Penyunting kode anda bisa membantu periksa di dalam fungsi seperti pemeriksaan kesalahan, kelengkapan kode, dll. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## <abbr title="juga disebut: serialization, parsing, marshalling">Konversi</abbr> data |
||||
|
|
||||
|
Jika contoh berikut dijalankan dan diakses browser melalui <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>, anda akan melihat respon: |
||||
|
|
||||
|
```JSON |
||||
|
{"item_id":3} |
||||
|
``` |
||||
|
|
||||
|
/// check | Periksa |
||||
|
|
||||
|
Perhatikan nilai fungsi yang diterima (dan dihasilkan) adalah `3`, sebagai `int` di Python, dan bukan string `"3"`. |
||||
|
|
||||
|
Sehingga dengan deklarasi tipe data **FastAPI** memberikan request otomatis <abbr title="konversi string dari request HTTP menjadi data Python">"parsing"</abbr>. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Validasi Data |
||||
|
|
||||
|
Tetapi jika di browser anda akses <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, anda akan melihat pesan kesalahan HTTP: |
||||
|
|
||||
|
```JSON |
||||
|
{ |
||||
|
"detail": [ |
||||
|
{ |
||||
|
"type": "int_parsing", |
||||
|
"loc": [ |
||||
|
"path", |
||||
|
"item_id" |
||||
|
], |
||||
|
"msg": "Input should be a valid integer, unable to parse string as an integer", |
||||
|
"input": "foo", |
||||
|
"url": "https://errors.pydantic.dev/2.1/v/int_parsing" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
Karena parameter path `item_id` bernilai `"foo"` yang bukan tipe data `int`. |
||||
|
|
||||
|
Kesalahan yang sama akan muncul jika menggunakan `float` daripada `int`, seperti di: <a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a> |
||||
|
|
||||
|
/// check | Periksa |
||||
|
|
||||
|
Dengan deklarasi tipe data Python, **FastAPI** melakukan validasi data. |
||||
|
|
||||
|
Perhatikan kesalahan tersebut juga menjelaskan validasi apa yang tidak sesuai. |
||||
|
|
||||
|
Validasi ini sangat membantu ketika mengembangkan dan men-*debug* kode yang berhubungan dengan API anda. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Dokumentasi |
||||
|
|
||||
|
Ketika anda membuka browser di <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, anda melihat dokumentasi API interaktif otomatis berikut: |
||||
|
|
||||
|
<img src="/img/tutorial/path-params/image01.png"> |
||||
|
|
||||
|
/// check | Periksa |
||||
|
|
||||
|
Dengan deklarasi tipe data Python yang sama, **FastAPI** membuat dokumentasi interaktif otomatis (terintegrasi Swagger UI). |
||||
|
|
||||
|
Perhatikan parameter path dideklarasikan sebagai integer. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Keuntungan basis-standar, dokumentasi alternatif |
||||
|
|
||||
|
Karena skema yang dibuat berasal dari standar <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md" class="external-link" target="_blank">OpenAPI</a>, maka banyak alat lain yang kompatibel. |
||||
|
|
||||
|
Sehingga **FastAPI** menyediakan dokumentasi alternatif (menggunakan ReDoc), yang bisa diakses di <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>: |
||||
|
|
||||
|
<img src="/img/tutorial/path-params/image02.png"> |
||||
|
|
||||
|
Cara yang sama untuk menggunakan tools kompatibel lainnya. Termasuk alat membuat kode otomatis untuk banyak bahasa. |
||||
|
|
||||
|
## Pydantic |
||||
|
|
||||
|
Semua validasi data dikerjakan di belakang layar oleh <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>, sehingga anda mendapatkan banyak kemudahan. Anda juga tahu proses ini akan ditangani dengan baik. |
||||
|
|
||||
|
Anda bisa mendeklarasikan tipe data dengan `str`, `float`, `bool` dan banyak tipe data kompleks lainnya. |
||||
|
|
||||
|
Beberapa tipe di atas akan dibahas pada bab berikutnya tutorial ini. |
||||
|
|
||||
|
## Urutan berpengaruh |
||||
|
|
||||
|
Ketika membuat *operasi path*, anda bisa menghadapi kondisi dimana *path* nya sudah tetap. |
||||
|
|
||||
|
Seperti `/users/me`, untuk mendapatkan data user yang sedang aktif. |
||||
|
|
||||
|
Kemudian anda bisa memiliki path `/users/{user_id}` untuk mendapatkan data user tertentu melalui user ID. |
||||
|
|
||||
|
karena *operasi path* dievaluasi melalui urutan, anda harus memastikan path untuk `/users/me` dideklarasikan sebelum `/user/{user_id}`: |
||||
|
|
||||
|
{* ../../docs_src/path_params/tutorial003.py hl[6,11] *} |
||||
|
|
||||
|
Sebaliknya, path `/users/{user_id}` juga akan sesuai dengan `/users/me`, "menganggap" menerima parameter `user_id` dengan nilai `"me"`. |
||||
|
|
||||
|
Serupa, anda juga tidak bisa mendefinisikan operasi path: |
||||
|
|
||||
|
{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *} |
||||
|
|
||||
|
Path pertama akan selalu digunakan karena path sesuai dengan yang pertama. |
||||
|
|
||||
|
## Nilai terdefinisi |
||||
|
|
||||
|
Jika ada *operasi path* yang menerima *parameter path*, tetapi anda ingin nilai valid *parameter path* sudah terdefinisi, anda bisa menggunakan standar Python <abbr title="Enumeration">`Enum`</abbr>. |
||||
|
|
||||
|
### Membuat class `Enum` |
||||
|
|
||||
|
Import `Enum` dan buat *sub-class* warisan dari `str` dan `Enum`. |
||||
|
|
||||
|
Dengan warisan dari `str` dokumen API mengetahui nilai nya harus berjenis `string` supaya bisa digunakan dengan benar. |
||||
|
|
||||
|
Kemudian buat atribut *class* dengan nilai tetap *string* yang benar: |
||||
|
|
||||
|
{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *} |
||||
|
|
||||
|
/// info |
||||
|
|
||||
|
<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Enumerasi (atau enum) tersedia di Python</a> sejak versi 3.4. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// tip | Tips |
||||
|
|
||||
|
"AlxexNet", "ResNet", dan "LeNet" adalah nama <abbr title="Secara teknis, arsitektur model Deep Learning">model</abbr> *Machine Learning*. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Mendeklarasikan *parameter path* |
||||
|
|
||||
|
Kemudian buat *parameter path* dengan tipe anotasi menggunakan *class* enum dari (`ModelName`) |
||||
|
|
||||
|
{* ../../docs_src/path_params/tutorial005.py hl[16] *} |
||||
|
|
||||
|
### Periksa dokumentasi |
||||
|
|
||||
|
Karena nilai yang tersedia untuk *parameter path* telah terdefinisi, dokumen interatik bisa memunculkan: |
||||
|
|
||||
|
<img src="/img/tutorial/path-params/image03.png"> |
||||
|
|
||||
|
### Bekerja dengan *enumarasi* Python |
||||
|
|
||||
|
Nilai *parameter path* akan menjadi *anggota enumerasi*. |
||||
|
|
||||
|
#### Membandingkan *anggota enumerasi* |
||||
|
|
||||
|
Anda bisa membandingkan parameter *path* dengan *anggota enumerasi* di enum `ModelName` yang anda buat: |
||||
|
|
||||
|
{* ../../docs_src/path_params/tutorial005.py hl[17] *} |
||||
|
|
||||
|
#### Mendapatkan *nilai enumerasi* |
||||
|
|
||||
|
Anda bisa mendapatkan nilai (`str` dalam kasus ini) menggunakan `model_name.value`, atau secara umum `anggota_enum_anda.value`: |
||||
|
|
||||
|
{* ../../docs_src/path_params/tutorial005.py hl[20] *} |
||||
|
|
||||
|
/// tip | Tips |
||||
|
|
||||
|
Anda bisa mengakses nilai `"lenet"` dnegan `ModelName.lenet.value`. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
#### Menghasilkan *anggota enumerasi* |
||||
|
|
||||
|
Anda bisa menghasilkan *anggota enumerasi* dari *operasi path* bahkan di body JSON bersarang (contoh `dict`). |
||||
|
|
||||
|
They will be converted to their corresponding values (strings in this case) before returning them to the client: |
||||
|
|
||||
|
{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *} |
||||
|
|
||||
|
Klien akan mendapatkan respon JSON seperti berikut: |
||||
|
|
||||
|
```JSON |
||||
|
{ |
||||
|
"model_name": "alexnet", |
||||
|
"message": "Deep Learning FTW!" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Parameter path berisi path |
||||
|
|
||||
|
Misalkan terdapat *operasi path* dengan path `/files/{file_path}`. |
||||
|
|
||||
|
Tetapi anda memerlukan `file_path` itu berisi *path*, seperti like `home/johndoe/myfile.txt`. |
||||
|
|
||||
|
Sehingga URL untuk file tersebut akan seperti: `/files/home/johndoe/myfile.txt`. |
||||
|
|
||||
|
### Dukungan OpenAPI |
||||
|
|
||||
|
OpenAPI tidak bisa mendeklarasikan *parameter path* berisi *path* di dalamnya, karena menyebabkan kondisi yang sulit di*test* dan didefinisikan. |
||||
|
|
||||
|
Tetapi, di **FastAPI** anda tetap bisa melakukannya dengan menggunakan *tools* internal dari Starlette. |
||||
|
|
||||
|
Dan dokumentasi tetap berfungsi walaupun tidak menambahkan keterangan bahwa parameter harus berisi *path*. |
||||
|
|
||||
|
### Konverter path |
||||
|
|
||||
|
Melalui Starlette anda bisa mendeklarasikan *parameter path* berisi *path* dengan URL seperti: |
||||
|
|
||||
|
``` |
||||
|
/files/{file_path:path} |
||||
|
``` |
||||
|
|
||||
|
Dikondisi ini nama parameter adalah `file_path` dan bagian terakhir `:path` menginformasikan parameter harus sesuai dengan setiap *path*. |
||||
|
|
||||
|
Sehingga anda bisa menggunakan: |
||||
|
|
||||
|
{* ../../docs_src/path_params/tutorial004.py hl[6] *} |
||||
|
|
||||
|
/// tip | Tips |
||||
|
|
||||
|
Anda mungkin perlu parameter berisi `/home/johndoe/myfile.txt` di awali garis belakang (`/`). |
||||
|
|
||||
|
Di kondisi ini, URL nya menjadi: `/files//home/johndoe/myfile.txt`, dengan dua garis belakang (`//`) di antara `files` dan `home`. |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Ringkasan |
||||
|
|
||||
|
Di **FastAPI** dengan menggunakan deklarasi tipe Python standar, pendek, intuitif, anda mendapatkan: |
||||
|
|
||||
|
* Dukungan editor: pemeriksaan kesalahan, autocompletion, dll. |
||||
|
* "<abbr title="konversi string dari request HTTP menjadi data Python">Parsing</abbr>" data. |
||||
|
* Validasi data. |
||||
|
* Annotasi API dan dokumentasi otomatis. |
||||
|
|
||||
|
Semua itu anda hanya perlu mendeklarasikan sekali saja. |
||||
|
|
||||
|
Ini adalah salah satu keunggulan **FastAPI** dibandingkan dengan *framework* lainnya (selain dari performa Python *native*c) |
Loading…
Reference in new issue