Verbinding maken met en query's uitvoeren op Azure SQL Database met behulp van Node.js en mssql npm-pakket
van toepassing op:Azure SQL Database-
In deze quickstart wordt beschreven hoe u een toepassing verbindt met een database in Azure SQL Database en query's uitvoert met behulp van Node.js en mssql. Deze quickstart volgt de aanbevolen benadering zonder wachtwoord om verbinding te maken met de database.
Wachtwoordloze verbindingen voor ontwikkelaars
Verbindingen zonder wachtwoord bieden een veiliger mechanisme voor toegang tot Azure-resources. De volgende stappen op hoog niveau worden gebruikt om verbinding te maken met Azure SQL Database met behulp van verbindingen zonder wachtwoord in dit artikel:
- Bereid uw omgeving voor op verificatie zonder wachtwoord.
- Voor een lokale omgeving: uw persoonlijke identiteit wordt gebruikt. Deze identiteit kan worden opgehaald uit een IDE, CLI of andere lokale ontwikkelhulpprogramma's.
- Voor een cloudomgeving: een beheerde identiteit wordt gebruikt.
- Verifieer in de omgeving met behulp van de
DefaultAzureCredential
uit de Azure Identity-bibliotheek om een geverifieerde referentie te verkrijgen. - Gebruik de geverifieerde referentie om Azure SDK-clientobjecten te maken voor toegang tot resources.
Meer informatie over verbindingen zonder wachtwoord vindt u op de hub zonder wachtwoord.
Voorwaarden
- Een Azure-abonnement
- Een database in Azure SQL Database die is geconfigureerd voor verificatie met Microsoft Entra ID (voorheen Azure Active Directory). Je kunt een database maken met behulp van de quickstart Database maken.
- Bash-ingeschakelde shell
- Node.js LTS
- Visual Studio Code
- Visual Studio Code App Service-extensie
- De nieuwste versie van de Azure CLI-
De databaseserver configureren
Voor beveiligde, wachtwoordloze verbindingen met Azure SQL Database zijn bepaalde databaseconfiguraties vereist. Controleer de volgende instellingen op uw logische server in Azure om verbinding te maken met Azure SQL Database in zowel lokale als gehoste omgevingen:
Voor lokale ontwikkelingsverbindingen moet u ervoor zorgen dat uw logische server zo is geconfigureerd dat het IP-adres van uw lokale computer en andere Azure-services verbinding kunnen maken:
Navigeer naar de pagina Netwerken van uw server.
Schakel het keuzerondje Geselecteerde netwerken in om extra configuratieopties weer te geven.
Selecteer Voeg uw IPv4-clientadres (xx.xx.xx.xx) toe om een firewallregel toe te voegen waarmee verbindingen vanaf het IPv4-adres van uw lokale computer worden ingeschakeld. U kunt ook + Een firewallregel toevoegen selecteren om een specifiek IP-adres van uw keuze in te voeren.
Zorg ervoor dat het selectievakje Azure-services en -resources toegang geven tot deze server is ingeschakeld.
Waarschuwing
Het inschakelen van de Toestaan dat Azure-services en -resources toegang krijgen tot deze server instelling is geen aanbevolen beveiligingspraktijk voor productiescenario's. Echte toepassingen moeten veiligere benaderingen implementeren, zoals sterkere firewallbeperkingen of configuraties van virtuele netwerken.
Meer informatie over databasebeveiligingsconfiguraties vindt u in de volgende bronnen:
Op de server moet ook Microsoft Entra-verificatie zijn ingeschakeld en moet een Microsoft Entra-beheerdersaccount zijn toegewezen. Voor lokale ontwikkelingsverbindingen moet het Microsoft Entra-beheerdersaccount een account zijn waarmee u zich lokaal kunt aanmelden bij Visual Studio of de Azure CLI. U kunt controleren of Microsoft Entra-verificatie is ingeschakeld op de Microsoft Entra ID pagina van uw logische server.
Als u een persoonlijk Azure-account gebruikt, moet u ervoor zorgen dat u Microsoft Entra hebt ingesteld en geconfigureerd voor Azure SQL Database om uw account toe te wijzen als serverbeheerder. Als u een bedrijfsaccount gebruikt, wordt de Microsoft Entra-id waarschijnlijk al voor u geconfigureerd.
Het project maken
Met de stappen in deze sectie maakt u een Node.js REST API.
Maak een nieuwe map voor het project en navigeer ernaartoe.
Initialiseer het project door de volgende opdracht uit te voeren in de terminal:
npm init -y
Installeer de vereiste pakketten die worden gebruikt in de voorbeeldcode in dit artikel:
npm install mssql express swagger-ui-express yamljs dotenv
Open het project in Visual Studio Code.
code .
Open het bestand
package.json
en voeg de volgende eigenschap en waarde toe na de eigenschap naam om het project voor ESM-modules te configureren."type": "module",
Toepassingscode voor Express.js maken
Als u de Express.js OpenAPI-toepassing wilt maken, maakt u verschillende bestanden:
Bestand | Beschrijving |
---|---|
.env.development |
Omgevingsbestand enkel voor lokale ontwikkeling. |
index.js |
Hoofdtoepassingsbestand, waarmee de Express.js-app op poort 3000 wordt gestart. |
person.js |
Express.js /person API-routeringsbestand om CRUD-bewerkingen af te handelen. |
openapi.js |
Express.js /api-docs route voor de gebruikersinterface van OpenAPI Explorer. Root wordt doorgestuurd naar deze route. |
openApiSchema.yml |
OpenAPI 3.0-schemabestand waarmee person-API wordt gedefinieerd. |
config.js |
Configuratiebestand voor het lezen van omgevingsvariabelen en het maken van het juiste mssql-verbindingsobject. |
database.js |
Databaseklasse voor het afhandelen van Azure SQL CRUD-bewerkingen met behulp van het mssql npm-pakket. |
./vscode/settings.json |
Negeer bestanden op glob-patroon tijdens de implementatie. |
Maak een
index.js
-bestand en voeg de volgende code toe:import express from 'express'; // Import App routes import person from './person.js'; import openapi from './openapi.js'; const port = process.env.PORT || 3000; const app = express(); // Connect App routes app.use('/api-docs', openapi); app.use('/persons', person); app.use('*', (_, res) => { res.redirect('/api-docs'); }); // Start the server app.listen(port, () => { console.log(`Server started on port ${port}`); });
Maak een
person.js
routebestand en voeg de volgende code toe:import express from 'express'; import { passwordConfig as SQLAuthentication, noPasswordConfig as PasswordlessConfig } from './config.js'; import { createDatabaseConnection } from './database.js'; const router = express.Router(); router.use(express.json()); const database = await createDatabaseConnection(SQLAuthentication); router.get('/', async (req, res) => { try { // Return a list of persons const persons = await database.readAll(); console.log(`persons: ${JSON.stringify(persons)}`); res.status(200).json(persons); } catch (err) { res.status(500).json({ error: err?.message }); } }); router.post('/', async (req, res) => { try { // add a person const person = req.body; console.log(`person: ${JSON.stringify(person)}`); const rowsAffected = await database.create(person); res.status(201).json({ rowsAffected }); } catch (err) { res.status(500).json({ error: err?.message }); } }); router.get('/:id', async (req, res) => { try { // Get the person with the specified ID const personId = req.params.id; console.log(`personId: ${personId}`); if (personId) { const result = await database.read(personId); console.log(`persons: ${JSON.stringify(result)}`); res.status(200).json(result); } else { res.status(404); } } catch (err) { res.status(500).json({ error: err?.message }); } }); router.put('/:id', async (req, res) => { try { // Update the person with the specified ID const personId = req.params.id; console.log(`personId: ${personId}`); const person = req.body; if (personId && person) { delete person.id; console.log(`person: ${JSON.stringify(person)}`); const rowsAffected = await database.update(personId, person); res.status(200).json({ rowsAffected }); } else { res.status(404); } } catch (err) { res.status(500).json({ error: err?.message }); } }); router.delete('/:id', async (req, res) => { try { // Delete the person with the specified ID const personId = req.params.id; console.log(`personId: ${personId}`); if (!personId) { res.status(404); } else { const rowsAffected = await database.delete(personId); res.status(204).json({ rowsAffected }); } } catch (err) { res.status(500).json({ error: err?.message }); } }); export default router;
Wijzig voor verificatie zonder wachtwoord de parameter die is doorgegeven aan
createDatabaseConnection
vanSQLAuthentication
inPasswordlessConfig
.const database = await createDatabaseConnection(PasswordlessConfig);
Maak een
openapi.js
routebestand en voeg de volgende code toe voor de OpenAPI UI Explorer:import express from 'express'; import { join, dirname } from 'path'; import swaggerUi from 'swagger-ui-express'; import yaml from 'yamljs'; import { fileURLToPath } from 'url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const router = express.Router(); router.use(express.json()); const pathToSpec = join(__dirname, './openApiSchema.yml'); const openApiSpec = yaml.load(pathToSpec); router.use('/', swaggerUi.serve, swaggerUi.setup(openApiSpec)); export default router;
Maak een
openApiSchema.yml
-bestand en voeg de volgende code toe, zodat de OpenAPI UI Explorer weet welke API's en modellen moeten worden weergegeven:openapi: 3.0.0 info: version: 1.0.0 title: Persons API paths: /persons: get: summary: Get all persons responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/Person' post: summary: Create a new person requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Person' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Person' /persons/{id}: parameters: - name: id in: path required: true schema: type: integer get: summary: Get a person by ID responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Person' '404': description: Person not found put: summary: Update a person by ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Person' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Person' '404': description: Person not found delete: summary: Delete a person by ID responses: '204': description: No Content '404': description: Person not found components: schemas: Person: type: object properties: id: type: integer readOnly: true firstName: type: string lastName: type: string
Het mssql-verbindingsobject configureren
Het mssql-pakket implementeert de verbinding met Azure SQL Database door een configuratie-instelling voor een verificatietype op te geven.
Maak in Visual Studio Code een
config.js
-bestand en voeg de volgende mssql-configuratiecode toe om te verifiëren bij Azure SQL Database.import * as dotenv from 'dotenv'; if(process.env.NODE_ENV === 'development') { dotenv.config({ path: `.env.${process.env.NODE_ENV}`, debug: true }); } // TIP: Port must be a number, not a string! const server = process.env.AZURE_SQL_SERVER; const database = process.env.AZURE_SQL_DATABASE; const port = +process.env.AZURE_SQL_PORT; const type = process.env.AZURE_SQL_AUTHENTICATIONTYPE; const user = process.env.AZURE_SQL_USER; const password = process.env.AZURE_SQL_PASSWORD; export const noPasswordConfig = { server, port, database, authentication: { type }, options: { encrypt: true } }; export const passwordConfig = { server, port, database, user, password, options: { encrypt: true } };
Een lokaal omgevingsvariabelebestand maken
Een .env.development
-bestand maken voor uw lokale omgevingsvariabelen
Voeg de volgende tekst toe en werk deze bij met uw waarden voor <YOURSERVERNAME>
en <YOURDATABASENAME>
.
AZURE_SQL_SERVER=<YOURSERVERNAME>.database.windows.net
AZURE_SQL_DATABASE=<YOURDATABASENAME>
AZURE_SQL_PORT=1433
AZURE_SQL_AUTHENTICATIONTYPE=azure-active-directory-default
Notitie
Configuratieobjecten zonder wachtwoord kunnen veilig worden doorgevoerd in broncodebeheer, omdat ze geen geheimen bevatten, zoals gebruikersnamen, wachtwoorden of toegangssleutels.
De code toevoegen om verbinding te maken met Azure SQL Database
Maak een
database.js
-bestand en voeg de volgende code toe:import sql from 'mssql'; let database = null; export default class Database { config = {}; poolconnection = null; connected = false; constructor(config) { this.config = config; } async connect() { try { this.poolconnection = await sql.connect(this.config); this.connected = true; console.log('Database connected successfully.'); return this.poolconnection; } catch (error) { console.error('Error connecting to the database:', error); this.connected = false; } } async disconnect() { try { if (this.connected) { await this.poolconnection.close(); this.connected = false; console.log('Database disconnected successfully.'); } } catch (error) { console.error('Error disconnecting from the database:', error); } } async executeQuery(query) { const request = this.poolconnection.request(); const result = await request.query(query); return result.rowsAffected[0]; } async create(data) { const request = this.poolconnection.request(); request.input('firstName', sql.NVarChar(255), data.firstName); request.input('lastName', sql.NVarChar(255), data.lastName); const result = await request.query( `INSERT INTO Person (firstName, lastName) VALUES (@firstName, @lastName)` ); return result.rowsAffected[0]; } async readAll() { const request = this.poolconnection.request(); const result = await request.query(`SELECT * FROM Person`); return result.recordsets[0]; } async read(id) { const request = this.poolconnection.request(); const result = await request .input('id', sql.Int, +id) .query(`SELECT * FROM Person WHERE id = @id`); return result.recordset[0]; } async update(id, data) { const request = this.poolconnection.request(); request.input('id', sql.Int, +id); request.input('firstName', sql.NVarChar(255), data.firstName); request.input('lastName', sql.NVarChar(255), data.lastName); const result = await request.query( `UPDATE Person SET firstName=@firstName, lastName=@lastName WHERE id = @id` ); return result.rowsAffected[0]; } async delete(id) { const idAsNumber = Number(id); const request = this.poolconnection.request(); const result = await request .input('id', sql.Int, idAsNumber) .query(`DELETE FROM Person WHERE id = @id`); return result.rowsAffected[0]; } async createTable() { if (process.env.NODE_ENV === 'development') { this.executeQuery( `IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Person') BEGIN CREATE TABLE Person ( id int NOT NULL IDENTITY, firstName varchar(255), lastName varchar(255) ); END` ) .then(() => { console.log('Table created'); }) .catch((err) => { // Table may already exist console.error(`Error creating table: ${err}`); }); } } } export const createDatabaseConnection = async (passwordConfig) => { database = new Database(passwordConfig); await database.connect(); await database.createTable(); return database; };
De app lokaal testen
De app is gereed om lokaal te worden getest. Zorg ervoor dat u bent aangemeld bij Azure Cloud in Visual Studio Code met hetzelfde account dat u hebt ingesteld als de beheerder voor uw database.
Voer de toepassing uit met de volgende opdracht. De app wordt gestart op poort 3000.
NODE_ENV=development node index.js
De tabel Person wordt gemaakt in de database wanneer u deze toepassing uitvoert.
Navigeer in een browser naar de OpenAPI Explorer op http://localhost:3000.
Vouw op de pagina Swagger UI de POST-methode uit en selecteer Probeer het.
Wijzig de voorbeeld-JSON om waarden voor de eigenschappen op te nemen. De id-eigenschap wordt genegeerd.
Selecteer uitvoeren om een nieuwe record toe te voegen aan de database. De API retourneert een geslaagd antwoord.
Vouw de methode GET uit op de pagina Swagger UI en selecteer Probeer het. Selecteer uitvoeren en de persoon die u zojuist hebt gemaakt, wordt geretourneerd.
Project configureren voor zip-implementatie
Maak een
.vscode
map en maak eensettings.json
bestand in de map.Voeg het volgende toe om omgevingsvariabelen en afhankelijkheden tijdens de zip-implementatie te negeren.
{ "appService.zipIgnorePattern": ["./.env*","node_modules{,/**}"] }
Implementeren in Azure App Service
De app is klaar om te worden geïmplementeerd in Azure. Visual Studio Code kan een Azure App Service maken en uw toepassing in één werkstroom implementeren.
Zorg ervoor dat de app is gestopt.
Meld u aan bij Azure als u dat nog niet hebt gedaan door de Azure te selecteren: meld u aan bij Azure Cloud opdracht in het opdrachtenpalet (Ctrl + Shift + P)
Klik in het Azure Explorer- venster van Visual Studio Code met de rechtermuisknop op het knooppunt App Services en selecteer Nieuwe web-app maken (geavanceerd).
Gebruik de volgende tabel om de App Service te maken:
Opdracht Waarde Voer een wereldwijd unieke naam in voor de nieuwe web-app. Voer een prompt in, zoals azure-sql-passwordless
. Voeg een unieke tekenreeks toe aan het einde, zoals123
.Selecteer een resourcegroep voor nieuwe resources. Selecteer +Een nieuwe resourcegroep maken selecteer vervolgens de standaardnaam. Selecteer een runtime stack. Selecteer een LTS-versie van de Node.js-stack. Selecteer een besturingssysteem. Selecteer Linux. Selecteer een locatie voor nieuwe resources. Selecteer een locatie dicht bij u in de buurt. Selecteer een Linux App Service-plan. Selecteer Nieuw App Service-plan maken. selecteer vervolgens de standaardnaam. Selecteer een prijscategorie. Selecteer gratis (F1). Selecteer een Application Insights-resource voor uw app. Selecteer Nu overslaan. Wacht tot u de melding ontvangt dat uw app is gemaakt voordat u doorgaat.
Vouw in de Azure Explorerhet knooppunt App Services uit en klik met de rechtermuisknop op uw nieuwe app.
Selecteer Uitrollen naar webapp.
Selecteer de hoofdmap van het JavaScript-project.
Wanneer het pop-upvenster van Visual Studio Code wordt weergegeven, selecteert u Implementeren.
Wanneer de implementatie is voltooid, werkt de app niet correct in Azure. U moet nog steeds de beveiligde verbinding tussen de App Service en de SQL-database configureren om uw gegevens op te halen.
De App Service verbinden met Azure SQL Database
De volgende stappen zijn vereist om het App Service-exemplaar te verbinden met Azure SQL Database:
- Maak een beheerde identiteit voor de App Service.
- Maak een SQL-databasegebruiker en koppel deze aan de door App Service beheerde identiteit.
- Wijs SQL-rollen toe aan de databasegebruiker die lees-, schrijf- en mogelijk andere machtigingen toestaat.
Er zijn meerdere hulpprogramma's beschikbaar om deze stappen te implementeren:
ServiceConnector is een hulpprogramma waarmee geverifieerde verbindingen tussen verschillende services in Azure worden gestroomlijnd. Service Connector ondersteunt momenteel het verbinden van een App Service met een Azure SQL-database via de Azure CLI met behulp van de opdracht az webapp connection create sql
. Met deze enkele opdracht worden de drie bovenstaande stappen voor u voltooid.
De beheerde identiteit maken met Service Connector
Voer de volgende opdracht uit in de Cloud Shell van Azure Portal. Cloud Shell heeft de nieuwste versie van de Azure CLI. Vervang de variabelen in <>
door uw eigen waarden.
az webapp connection create sql \
-g <app-service-resource-group> \
-n <app-service-name> \
--tg <database-server-resource-group> \
--server <database-server-name> \
--database <database-name> \
--system-identity
De App Service-app-instellingen controleren
U kunt de wijzigingen controleren die door Service Connector zijn aangebracht in de App Service-instellingen.
Klik in Visual Studio Code in de Azure explorer met de rechtermuisknop op uw App Service en selecteer Openen in de portal.
Ga naar de pagina Identity voor uw App Service. Op het tabblad Systeem dat is toegewezen, moet de status zijn ingesteld op Op. Deze waarde betekent dat een door het systeem toegewezen beheerde identiteit is ingeschakeld voor uw app.
Ga naar de pagina Configuration voor uw App Service. Op het tabblad Toepassingsinstellingen ziet u verschillende omgevingsvariabelen, die zich al in het mssql-configuratieobject bevinden.
AZURE_SQL_SERVER
AZURE_SQL_DATABASE
AZURE_SQL_PORT
AZURE_SQL_AUTHENTICATIONTYPE
Verwijder of wijzig de eigenschapsnamen of -waarden niet.
De geïmplementeerde toepassing testen
Blader naar de URL van de app om te testen of de verbinding met Azure SQL Database werkt. U kunt de URL van uw app vinden op de overzichtspagina van App Service.
De persoon die u lokaal hebt gemaakt, moet worden weergegeven in de browser. Gefeliciteerd! Uw toepassing is nu verbonden met Azure SQL Database in zowel lokale als gehoste omgevingen.
Suggestie
Als u tijdens het testen een 500 interne serverfout krijgt, kan dit worden veroorzaakt door uw databasenetwerkconfiguraties. Controleer of uw logische server is geconfigureerd met de instellingen die worden beschreven in de sectie De database configureren.
Deze bronnen opschonen
Wanneer u klaar bent met het werken met de Azure SQL Database, verwijdert u de resource om onbedoelde kosten te voorkomen.
Zoek in de zoekbalk van Azure Portal naar Azure SQL- en selecteer het overeenkomende resultaat.
Zoek en selecteer uw database in de lijst met databases.
Selecteer op de pagina Overzicht van uw Azure SQL Database Verwijderen.
Op de Azure-pagina die wordt geopend, waar u zeker weet dat u wilt verwijderen..., voert u de naam van uw database in om te bevestigen en selecteer vervolgens Verwijderen.
Voorbeeldcode
De voorbeeldcode voor deze toepassing is beschikbaar: