Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Prepare applications for Azure deployment by generating infrastructure code, Dockerfiles, and config files.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/services/app-service/templates/recipes/sql/source/nodejs.md
1# SQL Database — Node.js — REFERENCE ONLY23## Prisma + Azure SQL Setup45### npm Packages67```bash8npm install prisma @prisma/client mssql9npm install -D prisma10npx prisma init11```1213### Prisma Schema1415Update `prisma/schema.prisma`:1617```prisma18datasource db {19provider = "sqlserver"20url = env("DATABASE_URL")21}2223generator client {24provider = "prisma-client-js"25}2627model TodoItem {28id Int @id @default(autoincrement())29title String @db.NVarChar(200)30isComplete Boolean @default(false)31}32```3334### Database Client3536Create `src/db.js`:3738```javascript39const { PrismaClient } = require("@prisma/client");4041const prisma = new PrismaClient();42module.exports = { prisma };43```4445### API Endpoints4647Add to `src/index.js`:4849```javascript50const { prisma } = require("./db");5152app.get("/api/todos", async (req, res) => {53const todos = await prisma.todoItem.findMany();54res.json(todos);55});5657app.post("/api/todos", async (req, res) => {58const body = req.body || {};59const title = typeof body.title === "string" ? body.title.trim() : "";60if (!title) {61return res.status(400).json({ error: "title is required and must be a non-empty string" });62}63const isComplete = body.isComplete === undefined ? false : body.isComplete;64if (typeof isComplete !== "boolean") {65return res.status(400).json({ error: "isComplete must be a boolean" });66}67const todo = await prisma.todoItem.create({ data: { title, isComplete } });68res.status(201).json(todo);69});7071app.get("/api/todos/:id", async (req, res) => {72const todo = await prisma.todoItem.findUnique({73where: { id: parseInt(req.params.id) },74});75if (!todo) return res.status(404).json({ error: "Not found" });76res.json(todo);77});78```7980### Connection String8182**Azure (managed identity):**8384Set as app setting in Bicep — the format Prisma uses for SQL Server:85```86sqlserver://<server>.database.windows.net:1433;database=<db>;authentication=ActiveDirectoryMsi;clientId=<mi-client-id>87```8889```bicep90{ name: 'DATABASE_URL', value: 'sqlserver://${sqlServer.properties.fullyQualifiedDomainName}:1433;database=${sqlDatabase.name};authentication=ActiveDirectoryMsi;clientId=${managedIdentity.properties.clientId}' }91```9293**Local development (SQL auth):**9495```bash96# .env (local only — never commit)97DATABASE_URL="sqlserver://localhost:1433;database=myapp;user=<username>;password=<your-strong-password>;trustServerCertificate=true"98```99100### EF Migrations (postprovision hook)101102Create `infra/scripts/setup-db.sh`:103104```bash105#!/bin/bash106npx prisma migrate deploy --schema src/prisma/schema.prisma107```108109## Files to Add110111| File | Action |112|------|--------|113| `prisma/schema.prisma` | Create — data model definitions |114| `src/db.js` | Create — Prisma client instance |115| `src/index.js` | Modify — add CRUD endpoints |116| `package.json` | Modify — add prisma, @prisma/client |117118## Common Patterns119120- Use `prisma.todoItem.findMany()` for read-only queries121- Use `prisma.$disconnect()` in shutdown hooks for clean teardown122- Run `npx prisma generate` after schema changes to regenerate the client123