Lessons in this course (17)

4. Connecting a Vue app to SQL Server (through an API)

Intermediate★ Must knowLesson 4 of 17

Like every browser framework, Vue talks to an HTTP API, and the API talks to SQL Server (ASP.NET Core with EF Core/Dapper, or Node.js with mssql; with Nuxt the server/api routes can query SQL Server directly on the server).

ts
// src/services/api.ts
const BASE = import.meta.env.VITE_API_URL ?? "";
export async function api<T>(path: string, init?: RequestInit): Promise<T> {
  const res = await fetch(`${BASE}${path}`, { ...init, headers: { "Content-Type": "application/json", ...init?.headers } });
  if (!res.ok) throw new Error(`API ${res.status}`);
  return res.json();
}

// src/composables/useProducts.ts
import { ref, onMounted } from "vue";
import { api } from "../services/api";
export type Product = { id: number; name: string; price: number };
export function useProducts() {
  const products = ref<Product[]>([]);
  const loading = ref(true);
  const error = ref<string | null>(null);
  onMounted(async () => {
    try { products.value = await api<Product[]>("/api/products"); }
    catch { error.value = "Could not load products"; }
    finally { loading.value = false; }
  });
  return { products, loading, error };
}
vue
<!-- src/views/ProductsView.vue -->
<script setup lang="ts">
import { useProducts } from "../composables/useProducts";
const { products, loading, error } = useProducts();
</script>
<template>
  <p v-if="loading">Loading…</p>
  <p v-else-if="error">{{ error }}</p>
  <ul v-else><li v-for="p in products" :key="p.id">{{ p.name }} — ₹{{ p.price }}</li></ul>
</template>
ts
// Nuxt server route — runs on the server, safe to use SQL credentials
// server/api/products.get.ts
import sql from "mssql";
const pool = new sql.ConnectionPool(useRuntimeConfig().db).connect();
export default defineEventHandler(async () => (await (await pool).request().query("SELECT Id, Name, Price FROM dbo.Products")).recordset);

Dev proxy in vite.config.ts (server.proxy['/api']) avoids CORS locally; in production enable CORS on the API for the app's origin or serve both from the same domain.