やりたかったこと
-
Svelte公式チュートリアルの
fetch(uri)
の代わりに、
OpenAPI定義から自動生成した型定義されたTypescriptコードを使ってバックエンドと通信したい
タイトルに書いてしまったけどスキーマ駆動という語が妥当なのかはよくわからない...
調べ方が悪いのかやろうとする人にとっては当然の内容なのか、調べても出てこなかったので備忘録として
やったこと
公式チュートリアルを一通り眺めた状況からスタート
- SvelteKitの準備
- API定義からコード生成
- 実装
SvelteKitの準備
viteってビルドツールが全部やってくれた(全部Yes)
> yarn create vite
√ Project name: ... sample
√ Select a framework: » Svelte
√ Select a variant: » SvelteKit ↗
√ Which Svelte app template? » Skeleton project
√ Add type checking with TypeScript? » Yes, using TypeScript syntax
√ Add ESLint for code linting? ... No / Yes
√ Add Prettier for code formatting? ... No / Yes
√ Add Playwright for browser testing? ... No / Yes
あとはcd sample
してyarn
からのyarn dev
でとりあえず起動
API定義からコード生成
CLIでコード生成するパッケージをインストールして、
yarn add -D @openapitools/openapi-generator-cli
API定義からコード生成
yarn openapi-generator-cli generate -i ../spec/UserApi.yaml -g typescript-fetch -o ./src/lib/
-i
はソースファイル、-g
は生成時のテンプレート、-o
は出力先(事前にフォルダを作っておかなくても./src/lib/
に出力される)
参考:Stoplight StudioとOpenAPI Generatorを使ってみる
API定義はStoplightStudio起動時にサンプルで入ってたUserApi.yaml
を使った
実装
公式チュートリアルでpromiseを扱えればよさそうだったので、
<script lang="ts">
import { DefaultApi } from '$lib/apis/DefaultApi';
const api = new DefaultApi();
let userId = '';
let promise = api.getUsersUserId({ userId: null });
const fetchEvent = () => {
promise = api.getUsersUserId({ userId: userId });
};
</script>
ユーザID:<input bind:value={userId} />
<button on:click={fetchEvent}> fetch </button>
{#await promise then user}
{user.firstName + ' ' + user.lastName}
{/await}
として、IDを入力してボタン押下でユーザ名が表示されるコードを作成
$lib
はsrc/lib/
へのショートカットで、呼び出し側の階層に関わらず使えて便利らしいけどyarn dev
しないとパスが見つからないと言われる
動作確認はStoplightStudioのモックサーバで実施
(自動生成されたsrc/lib/runtime.js
で3100番ポートを指定した)
経緯という名の雑感
RTKQueryとかいうのが便利らしいけど(関数コンポーネントの)stateの実態がよく分からなくてReact挫折したのでSvelte触ってみてついでに研修でやったスキーマ駆動っぽいことがしたかった
研修でReactもやったはずなんだけどな
フロントとバックを分離したりコンポーネントに分割したりして変更容易性高めるとかスキーマに合わせて開発して齟齬無くすとか事前に型定義してTypescriptの恩恵受けるとか思想は分かっても技術力がついていかないのでできることを模索したらこうなった(´・ω・`)
とりあえず普通のtsファイルをインポートできるのか分からなかったけど書いたらできたのでよかったし、IDE支援も受けられるようになったので捗りそう
promise、await、asyncあたりがまだしっくりきていないというか挙動の脳内イメージができていないので頑張りたい
メモ
- API定義はspec(specification)でdefではないらしい
-
lang='typescript'
ではなくlang='ts'
らしい - import時のファイル名に
.ts
はつけなくていいらしい