Initial template: Vue 3 + FastAPI + SQLite full-stack with K8s deployment
Extracted from oil project — business logic removed, auth/db/deploy infrastructure generalized with APP_NAME placeholders. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
51
frontend/src/composables/useApi.js
Normal file
51
frontend/src/composables/useApi.js
Normal file
@@ -0,0 +1,51 @@
|
||||
const API_BASE = '' // same origin, uses vite proxy in dev
|
||||
|
||||
export function getToken() {
|
||||
return localStorage.getItem('auth_token') || ''
|
||||
}
|
||||
|
||||
export function setToken(token) {
|
||||
if (token) localStorage.setItem('auth_token', token)
|
||||
else localStorage.removeItem('auth_token')
|
||||
}
|
||||
|
||||
function buildHeaders(extra = {}) {
|
||||
const headers = { 'Content-Type': 'application/json', ...extra }
|
||||
const token = getToken()
|
||||
if (token) headers['Authorization'] = 'Bearer ' + token
|
||||
return headers
|
||||
}
|
||||
|
||||
async function request(path, opts = {}) {
|
||||
const headers = buildHeaders(opts.headers)
|
||||
const res = await fetch(API_BASE + path, { ...opts, headers })
|
||||
return res
|
||||
}
|
||||
|
||||
async function requestJSON(path, opts = {}) {
|
||||
const res = await request(path, opts)
|
||||
if (!res.ok) {
|
||||
let msg = `${res.status}`
|
||||
try {
|
||||
const body = await res.json()
|
||||
msg = body.detail || body.message || msg
|
||||
} catch {}
|
||||
const err = new Error(msg)
|
||||
err.status = res.status
|
||||
throw err
|
||||
}
|
||||
return res.json()
|
||||
}
|
||||
|
||||
function apiFn(path, opts = {}) {
|
||||
return request(path, opts)
|
||||
}
|
||||
|
||||
apiFn.raw = request
|
||||
apiFn.get = (path) => requestJSON(path)
|
||||
apiFn.post = (path, body) => requestJSON(path, { method: 'POST', body: JSON.stringify(body) })
|
||||
apiFn.put = (path, body) => requestJSON(path, { method: 'PUT', body: JSON.stringify(body) })
|
||||
apiFn.del = (path) => requestJSON(path, { method: 'DELETE' })
|
||||
apiFn.delete = (path) => requestJSON(path, { method: 'DELETE' })
|
||||
|
||||
export const api = apiFn
|
||||
Reference in New Issue
Block a user