Tech Blog

TypeScript + Fetch

Requirements

今回の環境

Vue 3 + Vue Router + Vuex + TypeScript + Vite

TL;DR

  1. OpenAPI Specification

openapi.yaml の作成

  # ./openapi.yaml

+ openapi: 3.0.3
+ info:
+   title: ''
+   version: ''
+ paths:
+   /login:
+     post:
+       operationId: obtainTokenPair
+       parameters: []
+       requestBody:
+         content:
+           application/json:
+             schema:
+               $ref: '#/components/schemas/Request'
+       responses:
+         '200':
+           content:
+             application/json:
+               schema:
+                 $ref: '#/components/schemas/Response'
+           description: ''
+       tags:
+       - login
+ components:
+   schemas:
+     Request:
+       type: object
+       properties:
+         username:
+           type: string
+         password:
+           type: string
+       required:
+       - username
+       - password
+     Response:
+       type: object
+       properties:
+         access:
+           type: string
+         refresh:
+           type: string
+
  1. TypeScript Fetch Client

typescript-fetch 生成

docker run --rm -v ${PWD}:/workspace -w /workspace \
  openapitools/openapi-generator-cli generate \
    -i openapi.yaml \
    -g typescript-fetch \
    -o src/types \
    --additional-properties=supportsES6=true,withInterfaces=true
  1. Use client

Vuex Module 追加

  // ./src/store/modules/user.ts

+ import { Module } from "vuex";
+ import { State as RootState } from "..";
+ import { Configuration, LoginApi, ObtainTokenPairRequest, Response } from "../../types";
+
+ interface State extends Response {
  ...
+ }
+
+ const store: Module<State, RootState> = {
+   namespaced: true,
+   state() {
+     return {
+       access: undefined,
+     };
+   },
+   mutations: {
+     setTokens(state: State, payload: Response) {
+       state.access = payload.access;
+       state.refresh = payload.refresh;
+     },
+   },
+   actions: {
+     async login({ commit }, payload: ObtainTokenPairRequest) {
+       try {
+         const config = new Configuration({
+           basePath: process.env.VUE_APP_BASE_PATH,
+         });
+       const data = await new LoginApi(config).obtainTokenPair(
+         payload
+       );
+       commit("setTokens", data);
+     } catch (error) {
+       throw error;
+     }
+   },
+   getters: {
+     hasToken(state: State) {
+       return state.access;
+     },
+   },
+ },
+
+ export default store;
+

参考にしたページ