Bagikan melalui


Koneksi ke dan kueri Azure SQL Database menggunakan paket npm Node.js dan mssql

Berlaku untuk:Azure SQL Database

Mulai cepat ini menjelaskan cara menyambungkan aplikasi ke database di Azure SQL Database dan melakukan kueri menggunakan Node.js dan mssql. Mulai cepat ini mengikuti pendekatan tanpa kata sandi yang direkomendasikan untuk menyambungkan ke database.

Koneksi tanpa kata sandi untuk pengembang

Koneksi tanpa kata sandi menawarkan mekanisme yang lebih aman untuk mengakses sumber daya Azure. Langkah-langkah tingkat tinggi berikut digunakan untuk menyambungkan ke Azure SQL Database menggunakan koneksi tanpa kata sandi dalam artikel ini:

  • Siapkan lingkungan Anda untuk autentikasi bebas kata sandi.
    • Untuk lingkungan lokal: Identitas pribadi Anda digunakan. Identitas ini dapat ditarik dari IDE, CLI, atau alat pengembangan lokal lainnya.
    • Untuk lingkungan cloud: Identitas terkelola digunakan.
  • Autentikasi di lingkungan menggunakan DefaultAzureCredential dari pustaka Azure Identity untuk mendapatkan kredensial terverifikasi.
  • Gunakan kredensial terverifikasi untuk membuat objek klien Azure SDK untuk akses sumber daya.

Anda dapat mempelajari lebih lanjut tentang koneksi tanpa kata sandi di hub tanpa kata sandi.

Prasyarat

Mengonfigurasi server database

Koneksi aman tanpa kata sandi ke Azure SQL Database memerlukan konfigurasi database tertentu. Verifikasi pengaturan berikut di server logis Anda di Azure untuk menyambungkan dengan benar ke Azure SQL Database di lingkungan lokal dan yang dihosting:

  1. Untuk koneksi pengembangan lokal, pastikan server logis Anda dikonfigurasi untuk memungkinkan alamat IP komputer lokal Anda dan layanan Azure lainnya tersambung:

    • Navigasi ke halaman Jaringan server Anda.

    • Alihkan tombol radio Jaringan terpilih untuk menampilkan opsi konfigurasi tambahan.

    • Pilih Tambahkan alamat IPv4 klien Anda(xx.xx.xx.xx) untuk menambahkan aturan firewall yang akan mengaktifkan koneksi dari alamat IPv4 komputer lokal Anda. Atau, Anda juga dapat memilih + Tambahkan aturan firewall untuk memasukkan alamat IP tertentu pilihan Anda.

    • Pastikan kotak centang Izinkan layanan dan sumber daya Azure untuk mengakses server ini dipilih.

      Cuplikan layar memperlihatkan cara mengonfigurasi aturan firewall.

      Peringatan

      Mengaktifkan pengaturan Izinkan layanan dan sumber daya Azure untuk mengakses server ini bukanlah praktik keamanan yang direkomendasikan untuk skenario produksi. Aplikasi nyata harus menerapkan pendekatan yang lebih aman, seperti pembatasan firewall yang lebih kuat atau konfigurasi jaringan virtual.

      Anda bisa membaca selengkapnya tentang konfigurasi keamanan database pada sumber daya berikut:

  2. Server juga harus mengaktifkan autentikasi Microsoft Entra dan memiliki akun admin Microsoft Entra yang ditetapkan. Untuk koneksi pengembangan lokal, akun admin Microsoft Entra harus menjadi akun yang juga dapat Anda masuk ke Visual Studio atau Azure CLI dengan secara lokal. Anda dapat memverifikasi apakah server Anda mengaktifkan autentikasi Microsoft Entra di halaman ID Microsoft Entra server logis Anda.

    Cuplikan layar memperlihatkan cara mengaktifkan autentikasi Microsoft Entra.

  3. Jika Anda menggunakan akun Azure pribadi, pastikan Anda memiliki penyiapan Microsoft Entra dan dikonfigurasi untuk Azure SQL Database untuk menetapkan akun Anda sebagai admin server. Jika Anda menggunakan akun perusahaan, ID Microsoft Entra kemungkinan besar sudah dikonfigurasi untuk Anda.

Membuat proyek

Langkah-langkah di bagian ini membuat REST API Node.js.

  1. Buat direktori baru untuk proyek dan navigasikan ke dalamnya.

  2. Inisialisasi proyek dengan menjalankan perintah berikut di terminal:

    npm init -y
    
  3. Instal paket yang diperlukan yang digunakan dalam kode sampel dalam artikel ini:

    npm install mssql swagger-ui-express yamljs
    
  4. Instal paket pengembangan yang digunakan dalam kode sampel dalam artikel ini:

    npm install --save-dev dotenv 
    
  5. Buka proyek di Visual Studio Code.

    code .
    
  6. Buka file package.json dan tambahkan properti dan nilai berikut setelah properti nama untuk mengonfigurasi proyek untuk modul ESM.

    "type": "module",
    

Membuat kode aplikasi Express.js

Untuk membuat aplikasi openAPI Express.js, Anda akan membuat beberapa file:

File Deskripsi
.env.development File lingkungan khusus pengembangan lokal.
index.js File aplikasi utama, yang memulai aplikasi Express.js pada port 3000.
person.js Express.js file API rute /person untuk menangani operasi CRUD.
openapi.js Express.js rute /api-docs untuk UI penjelajah OpenAPI. Akar mengalihkan ke rute ini.
openApiSchema.yml File skema OpenAPI 3.0 yang menentukan API Orang.
config.js File konfigurasi untuk membaca variabel lingkungan dan membangun objek koneksi mssql yang sesuai.
database.js Kelas database untuk menangani operasi CRUD Azure SQL menggunakan paket mssql npm.
./vscode/settings.json Abaikan file dengan pola glob selama penyebaran.
  1. Buat file index.js dan tambahkan kode berikut:

    import express from 'express';
    import { config } from './config.js';
    import Database from './database.js';
    
    // Import App routes
    import person from './person.js';
    import openapi from './openapi.js';
    
    const port = process.env.PORT || 3000;
    
    const app = express();
    
    // Development only - don't do in production
    // Run this to create the table in the database
    if (process.env.NODE_ENV === 'development') {
      const database = new Database(config);
      database
        .executeQuery(
          `CREATE TABLE Person (id int NOT NULL IDENTITY, firstName varchar(255), lastName varchar(255));`
        )
        .then(() => {
          console.log('Table created');
        })
        .catch((err) => {
          // Table may already exist
          console.error(`Error creating table: ${err}`);
        });
    }
    
    // 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}`);
    });
    
  2. Buat file rute person.js dan tambahkan kode berikut:

    import express from 'express';
    import { config } from './config.js';
    import Database from './database.js';
    
    const router = express.Router();
    router.use(express.json());
    
    // Development only - don't do in production
    console.log(config);
    
    // Create database object
    const database = new Database(config);
    
    router.get('/', async (_, 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 {
        // Create 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;
    
    
  3. Buat file rute openapi.js dan tambahkan kode berikut untuk penjelajah UI OpenAPI:

    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;
    
  4. Buat file skema openApiSchema.yml dan tambahkan YAML berikut:

    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
    

Mengonfigurasi objek koneksi mssql

Paket mssql mengimplementasikan koneksi ke Azure SQL Database dengan menyediakan pengaturan konfigurasi untuk jenis autentikasi.

  1. Di Visual Studio Code, buat file config.js dan tambahkan kode konfigurasi mssql berikut untuk mengautentikasi ke Azure SQL Database.

    import * as dotenv from 'dotenv';
    dotenv.config({ path: `.env.${process.env.NODE_ENV}`, debug: true });
    
    const server = process.env.AZURE_SQL_SERVER;
    const database = process.env.AZURE_SQL_DATABASE;
    const port = parseInt(process.env.AZURE_SQL_PORT);
    const type = process.env.AZURE_SQL_AUTHENTICATIONTYPE;
    
    export const config = {
        server,
        port,
        database,
        authentication: {
            type
        },
        options: {
            encrypt: true
        }
    };
    
  2. Buat file .env.development untuk variabel lingkungan lokal Anda dan tambahkan teks berikut dan perbarui dengan nilai Anda untuk <YOURSERVERNAME> dan <YOURDATABASENAME>.

    AZURE_SQL_SERVER=<YOURSERVERNAME>.database.windows.net
    AZURE_SQL_DATABASE=<YOURDATABASENAME>
    AZURE_SQL_PORT=1433
    AZURE_SQL_AUTHENTICATIONTYPE=azure-active-directory-default
    

Catatan

Objek konfigurasi tanpa kata sandi aman untuk berkomitmen pada kontrol sumber, karena tidak berisi rahasia apa pun seperti nama pengguna, kata sandi, atau kunci akses.

  1. Buat .vscode folder dan buat file settings.json di folder .

  2. Tambahkan hal berikut untuk mengabaikan variabel dan dependensi lingkungan selama penyebaran zip.

    {
        "appService.zipIgnorePattern": ["./.env*","node_modules{,/**}"]
    }
    

Menambahkan kode untuk menyambungkan ke Azure SQL Database

  1. Buat file database.js dan tambahkan kode berikut:

    import sql from 'mssql';
    
    export default class Database {
      config = {};
      poolconnection = null;
      connected = false;
    
      constructor(config) {
        this.config = config;
        console.log(`Database: config: ${JSON.stringify(config)}`);
      }
    
      async connect() {
        try {
          console.log(`Database connecting...${this.connected}`);
          if (this.connected === false) {
            this.poolconnection = await sql.connect(this.config);
            this.connected = true;
            console.log('Database connection successful');
          } else {
            console.log('Database already connected');
          }
        } catch (error) {
          console.error(`Error connecting to database: ${JSON.stringify(error)}`);
        }
      }
    
      async disconnect() {
        try {
          this.poolconnection.close();
          console.log('Database connection closed');
        } catch (error) {
          console.error(`Error closing database connection: ${error}`);
        }
      }
    
      async executeQuery(query) {
        await this.connect();
        const request = this.poolconnection.request();
        const result = await request.query(query);
    
        return result.rowsAffected[0];
      }
    
      async create(data) {
        await this.connect();
        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() {
        await this.connect();
        const request = this.poolconnection.request();
        const result = await request.query(`SELECT * FROM Person`);
    
        return result.recordsets[0];
      }
    
      async read(id) {
        await this.connect();
    
        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) {
        await this.connect();
    
        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) {
        await this.connect();
    
        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];
      }
    }
    

Uji aplikasi secara lokal

Aplikasi ini siap untuk diuji secara lokal. Pastikan Anda masuk ke Azure Cloud di Visual Studio Code dengan akun yang sama dengan yang Anda tetapkan sebagai admin untuk database Anda.

  1. Jalankan aplikasi dengan perintah berikut. Aplikasi dimulai pada port 3000.

    NODE_ENV=development node index.js
    

    Tabel Orang dibuat dalam database saat Anda menjalankan aplikasi ini.

  2. Di browser, navigasikan ke penjelajah OpenAPI di http://localhost:3000.

  3. Pada halaman UI Swagger, perluas metode POST dan pilih Coba.

  4. Ubah sampel JSON untuk menyertakan nilai untuk properti. Properti ID diabaikan.

    Cuplikan layar yang menunjukkan cara menguji API.

  5. Pilih Jalankan untuk menambahkan rekaman baru ke database. API mengembalikan respons yang berhasil.

  6. Perluas metode GET pada halaman UI Swagger dan pilih Coba. Pilih Jalankan, dan orang yang baru saja Anda buat dikembalikan.

Menyebarkan ke Azure App Service

Aplikasi ini siap disebarkan ke Azure. Visual Studio Code dapat membuat Azure App Service dan menyebarkan aplikasi Anda dalam satu alur kerja.

  1. Pastikan aplikasi dihentikan.

  2. Masuk ke Azure, jika Anda belum melakukannya, dengan memilih perintah Azure: Masuk ke Azure Cloud di Palet Perintah (Ctrl + Shift + P)

  3. Di jendela Azure Explorer Visual Studio Code, klik kanan pada simpul App Services dan pilih Buat Aplikasi Web Baru (Tingkat Lanjut).

  4. Gunakan tabel berikut untuk membuat App Service:

    Prompt Nilai
    Masukkan nama yang unik secara global untuk aplikasi web yang baru. Masukkan perintah seperti azure-sql-passwordless. Pasca-tertunda string unik seperti 123.
    Pilih grup sumber daya untuk sumber daya baru. Pilih +Buat grup sumber daya baru lalu pilih nama default.
    Pilih tumpukan runtime. Pilih versi LTS dari tumpukan Node.js.
    Pilih OS. Pilih Linux.
    Pilih lokasi untuk sumber daya baru. Pilih lokasi yang dekatb dengan Anda.
    Pilih paket Linux App Service. Pilih Buat paket App Service baru. lalu pilih nama default.
    Pilih tingkat harga. Pilih Gratis (F1).
    Pilih sumber daya Application Insights untuk aplikasi Anda. Pilih Lewati untuk saat ini.
  5. Tunggu hingga pemberitahuan bahwa aplikasi Anda dibuat sebelum melanjutkan.

  6. Di Azure Explorer, perluas simpul App Services dan klik kanan aplikasi baru Anda.

  7. Pilih Sebarkan ke Aplikasi Web.

    Cuplikan layar Visual Studio Code di penjelajah Azure dengan Sebarkan ke Aplikasi Web disorot.

  8. Pilih folder akar proyek JavaScript.

  9. Saat pop-up Visual Studio Code muncul, pilih Sebarkan.

Setelah penyebaran selesai, aplikasi tidak berfungsi dengan benar di Azure. Anda masih perlu mengonfigurasi koneksi aman antara App Service dan database SQL untuk mengambil data Anda.

Koneksi App Service ke Azure SQL Database

Langkah-langkah berikut diperlukan untuk menyambungkan instans App Service ke Azure SQL Database:

  1. Buat identitas terkelola untuk App Service.
  2. Buat pengguna database SQL dan kaitkan dengan identitas terkelola App Service.
  3. Tetapkan peran SQL ke pengguna database yang memungkinkan izin baca, tulis, dan berpotensi lainnya.

Ada beberapa alat yang tersedia untuk menerapkan langkah-langkah ini:

Service Koneksi or adalah alat yang menyederhanakan koneksi terautentikasi antara berbagai layanan di Azure. Service Koneksi or saat ini mendukung menyambungkan App Service ke database Azure SQL melalui Azure CLI menggunakan az webapp connection create sql perintah . Perintah tunggal ini menyelesaikan tiga langkah yang disebutkan di atas untuk Anda.

Membuat identitas terkelola dengan Service Koneksi or

Jalankan perintah berikut di Cloud Shell portal Azure. Cloud Shell memiliki versi terbaru Azure CLI. Ganti variabel dengan <> nilai Anda sendiri.

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

Memverifikasi pengaturan aplikasi App Service

Anda dapat memverifikasi perubahan yang dibuat oleh Koneksi Layanan pada pengaturan App Service.

  1. Di Visual Studio Code, di penjelajah Azure, klik kanan App Service Anda dan pilih Buka di portal.

  2. Navigasi ke halaman Identitas untuk App Service Anda. Di bawah tab Sistem yang ditetapkan, Status harus diatur ke Aktif. Nilai ini berarti bahwa identitas terkelola yang ditetapkan sistem diaktifkan untuk aplikasi Anda.

  3. Navigasi ke halaman Konfigurasi untuk App Service Anda. Di bawah tab Pengaturan Aplikasi, Anda akan melihat beberapa variabel lingkungan, yang sudah ada di objek konfigurasi mssql.

    • AZURE_SQL_SERVER
    • AZURE_SQL_DATABASE
    • AZURE_SQL_PORT
    • AZURE_SQL_AUTHENTICATIONTYPE

    Jangan hapus atau ubah nama atau nilai properti.

Menguji aplikasi yang disebarkan

Telusuri ke URL aplikasi untuk menguji bahwa koneksi ke Azure SQL Database berfungsi. Anda dapat menemukan URL aplikasi Anda di halaman ringkasan App Service.

Orang yang Anda buat secara lokal harus ditampilkan di browser. Selamat! Aplikasi Anda sekarang terhubung ke Azure SQL Database di lingkungan lokal dan yang dihosting.

Tip

Jika Anda menerima kesalahan 500 Server Internal saat pengujian, itu mungkin karena konfigurasi jaringan database Anda. Verifikasi bahwa server logis Anda dikonfigurasi dengan pengaturan yang diuraikan di bagian Konfigurasikan database .

Membersihkan sumber daya

Setelah selesai bekerja dengan Azure SQL Database, hapus sumber daya untuk menghindari biaya yang tidak diinginkan.

  1. Di bilah pencarian portal Azure, cari Azure SQL dan pilih hasil yang cocok.

  2. Temukan dan pilih database Anda dalam daftar database.

  3. Pada halaman Gambaran Umum Azure SQL Database Anda, pilih Hapus.

  4. Pada halaman Azure yang Anda yakin ingin hapus... yang terbuka, ketik nama database Anda untuk mengonfirmasi, lalu pilih Hapus.

Kode Sampel

Kode sampel untuk aplikasi ini tersedia di GitHub.

Langkah berikutnya