So erstellen Sie mit Docker ~ Sequelize ~ eine [TypeScript + Vue + Express + MySQL] -Umgebung

Inhalt

Dieses Mal verwenden wir Sequelize, das ORM von Node.js, um vom Express-Server auf MySQL zuzugreifen, Daten zu erfassen und zu antworten.

Da die Erstellung des Express-Servers und der einfachen API durch den vorherigen Artikel abgeschlossen wurde, werde ich mich dieses Mal auf die Einführung von Sequelize und die Erstellung von Model konzentrieren.

Inhalt bis zum letzten Mal

Erstellen einer Umgebung für [TypeScript + Vue + Express + MySQL] mit Docker ~ Vue Edition ~ Erstellen einer Umgebung von [TypeScript + Vue + Express + MySQL] mit Docker ~ MySQL Edition ~ Erstellen einer Umgebung von [TypeScript + Vue + Express + MySQL] mit Docker ~ Express ~

Arbeitsablauf

  1. Richten Sie ein Netzwerk zwischen Containern ein
  2. Sequelize eingeführt
  3. Modellerstellung
  4. Vervollständigen Sie die GetTests-API
  5. Rufen Sie die API mit Axios von der Vorderseite aus auf
  6. Binden und rendern Sie die Antwort an Vuex

1. Richten Sie ein Netzwerk zwischen Containern ein

docker-compose.yml

version: "3"
services:
  app:
    container_name: app_container
    build: ./docker/app
    ports:
      - 8080:8080
    volumes:
      - ./app:/app
    stdin_open: true
    tty: true
    environment:
      TZ: Asia/Tokyo
    command: yarn serve
    networks:                          #Netzwerk hinzufügen
      - default

  api:
    container_name: api_container
    build: ./docker/api
    ports:
      - 3000:3000
    volumes:
      - ./api:/api
    tty: true
    environment:
      CHOKIDAR_USEPOLLING: 1
      TZ: Asia/Tokyo
    depends_on:
      - db
    command: yarn nodemon
    networks:                          #Netzwerk hinzufügen
      - default

  db:
    container_name: db_container
    build: ./docker/db
    image: mysql:5.7
    ports:
      - 3306:3306
    volumes:
      - ./db/conf/my.cnf:/etc/mysql/conf.d/mysql.cnf
      - ./db/init_db:/docker-entrypoint-initdb.d
      - test_data:/var/lib/mysql
    environment:
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - TZ="Asia/Tokyo"
    networks:                          #Netzwerk hinzufügen
      - default

networks:                              #Netzwerk hinzufügen
  default:

volumes:
  test_data:

Durch die Verbindung mit einem gemeinsamen Netzwerk ist es möglich, zwischen den einzelnen Komponenten zu kommunizieren.

Container-Start

$ docker-compose up -d

2. Sequelize eingeführt

Von hier aus werden wir Sequelize einführen, ein ORM für Node.js (das Daten aus einer relationalen Datenbank erfasst und bearbeitet) und Daten aus der Datenbank abruft.

Zugang zum Container

$ docker exec -it api_container sh

Installieren Sie die erforderlichen Bibliotheken

$ yarn add [email protected] sequelize-typescript reflect-metadata mysql2 log4js cors
$ yarn add --dev dotenv @types/validator @types/bluebird @types/cors @types/dotenv

* Abhängig von der Version von sequelize kann ein Fehler auftreten. Sie müssen daher die Version zum Zeitpunkt der Installation überprüfen! </ font>

api/index.ts

import cors from 'cors' //hinzufügen
import express from 'express'
import router from './routes/index'

const app = express()
const port = 3000

app.use(cors()) //hinzufügen

app.use('/api', router)

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

3. Modellerstellung

api/models/settings/.env

MYSQL_DATABASE=test_db
MYSQL_USER={Was wurde beim Erstellen des MySQL-Containers festgelegt?}
MYSQL_PASSWORD={Was wurde beim Erstellen des MySQL-Containers festgelegt?}
MYSQL_ROOT_PASSWORD={Was wurde beim Erstellen des MySQL-Containers festgelegt?}

Dies ist die gleiche Einstellung wie .env im Stammverzeichnis.

api/models/settings/db_setting.ts

import dotenv from 'dotenv'

dotenv.config({ path: __dirname + '/.env' })

interface DatabaseTypes {
  database: string | undefined
  user: string | undefined
  password: string | undefined
}

export const dbSetting: DatabaseTypes = {
  database: process.env.MYSQL_DATABASE,
  user: process.env.MYSQL_USER,
  password: process.env.MYSQL_PASSWORD,
}

Legen Sie das Passwort und die Tabelle für Sequelize fest.

api/models/test.ts

import {
  Table,
  Model,
  Column,
  DataType,
  PrimaryKey,
  AutoIncrement,
} from 'sequelize-typescript'

@Table({
  modelName: 'test',
  tableName: 'test',
})
export class Test extends Model<Test> {
  @PrimaryKey
  @AutoIncrement
  @Column(DataType.INTEGER)
  readonly id!: number

  @Column(DataType.STRING)
  name!: string

  @Column(DataType.STRING)
  description!: string
}

Erstellen Sie ein Modell für die Testtabelle. Auf Dekorationsbasis beschrieben.

Ich erhalte einen TypeScript-Fehler, daher habe ich eine Regel hinzugefügt.

api/tsconfig.json

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "include": ["./**/*"]
}

Bearbeiten Sie die obigen tsconfig-Einstellungen

api/models/index.ts

import log4js from 'log4js'
import { Sequelize } from 'sequelize-typescript'
import { dbSetting } from './settings/db_setting'
import { Test } from './test'

const logger = log4js.getLogger('mysql')

export default new Sequelize({
  dialect: 'mysql',
  timezone: '+09:00',
  port: 3306,
  host: 'db',
  username: dbSetting['user'],
  password: dbSetting['password'],
  database: dbSetting['database'],
  logging: (sql: string) => {
    logger.info(sql)
  },
  define: { timestamps: false, underscored: true },
  pool: { max: 5, min: 0, idle: 10000, acquire: 30000 },
  models: [Test],
})

export { Test }

Dies ist das Herz dieser Zeit. Wenn Sie eine Fehlermeldung erhalten, sollte diese hier sein. Wenn die Bibliotheksversion unterschiedlich ist oder die tsconfig-Einstellungen nicht korrekt sind, tritt hier ein Fehler auf.

4. Vervollständigen Sie die GetTests-API

api/routes/tests/get_tests.ts

import { Request, Response } from 'express'
import { Handler } from '../../core/handler'
import { NO_DATA_EXISTS } from '../../constants/error'
import { Test } from '../../models/index'

export class GetTests {
  handler: Handler

  constructor(req: Request, res: Response) {
    this.handler = new Handler(req, res)
  }

  /**
   *Hauptverarbeitung
   */
  async main() {
    const data = await this.getTests()

    if (!data) {
      return this.handler.error(NO_DATA_EXISTS)
    }

    return this.handler.json(data)
  }

  /**
   *Holen Sie sich alle Testdaten
   */
  getTests() {
    return Test.findAll({
      attributes: ['id', 'name', 'description'],
    })
  }
}

Als Verarbeitungsablauf

  1. Die Hauptfunktion wird instanziiert und aufgerufen
  2. Die Funktion getTests wird innerhalb der Hauptfunktion aufgerufen
  3. Rufen Sie Daten aus der Testtabelle ab, indem Sie die Funktion findAll (alle Daten abrufen) für das Testmodell in getTests ausführen
  4. Wenn der Rückgabewert der Funktion getTests nicht vorhanden ist, wird ein Fehler zurückgegeben. Wenn er vorhanden ist, werden Daten im JSON-Format zurückgegeben.

Bestätigung!

Zugriff auf localhost: 3000 / api / tests! スクリーンショット 2020-09-22 2.35.05.png Es ist in Ordnung, wenn die tatsächlichen Daten in JSON zurückgegeben werden!

Erstellen Sie eine API, um eine aus der angegebenen ID abzurufen

api/routes/tests/get_test_by_id.ts

import { Request, Response } from 'express'
import { Handler } from '../../core/handler'
import { PARAMETER_INVALID, NO_DATA_EXISTS } from '../../constants/error'
import { Test } from '../../models/index'

type Params = {
  test_id: number
}

export class GetTestById {
  handler: Handler
  params: Params

  constructor(req: Request, res: Response) {
    this.handler = new Handler(req, res)

    this.params = {
      test_id: Number(req.params.test_id),
    }
  }

  /**
   *Hauptverarbeitung
   */
  async main() {
    if (!this.params.test_id) {
      return this.handler.error(PARAMETER_INVALID)
    }

    const data = await this.getTest()

    if (!data) {
      return this.handler.error(NO_DATA_EXISTS)
    }

    return this.handler.json(data)
  }

  /**
   *Holen Sie sich alle Testdaten
   */
  getTest() {
    return Test.findOne({
      attributes: ['id', 'name', 'description'],
      where: {
        id: this.params.test_id,
      },
    })
  }
}

Suchen Sie diesmal in der Funktion findOne (eine entsprechende Daten abrufen) nach der where-Klausel, um die Daten mit der entsprechenden ID abzurufen.

testsController.ts

import { Router } from 'express'
import { GetTests } from '../tests/get_tests'
import { GetTestById } from '../tests/get_test_by_id' //hinzufügen

const router = Router()

router.get('/', (req, res, next) => {
  new GetTests(req, res).main().catch(next)
})

router.get('/:test_id', (req, res, next) => {   //hinzufügen
  new GetTestById(req, res).main().catch(next)  //hinzufügen
})                                              //hinzufügen

export default router

Die zu durchsuchende ID wird als Abfrage der URL an die GetTestById-Klasse übergeben.

Bestätigung!

Zugriff auf localhost: 3000 / api / tests / 1 スクリーンショット 2020-09-22 2.39.56.png

Wenn die Daten von / tests / ** {hier angegebene ID} ** zurückgegeben werden, ist dies erfolgreich! Bitte überprüfen Sie mit anderen IDs als Test.

5. Rufen Sie die API mit Axios von der Vorderseite aus auf

Zu diesem Zeitpunkt ist die Serverseite abgeschlossen. Von hier aus nehmen wir Einstellungen vor, um die erstellte API tatsächlich von vorne aufzurufen.

Raus aus dem Container

$ exit

Greifen Sie auf den App-Container zu

$ docker exec -it app_container sh

Axios eingeführt

$ yarn add axios

app/src/utils/axios.ts

import axios from 'axios'

export const api = axios.create({
  baseURL: 'http://localhost:3000/api',
})

Definieren Sie ein Modul für beide Gegenmaßnahmen und die Standard-URL-Konvertierung. Beim Anruf ist es möglich, mit api.get oder api.post anzurufen.

app/src/store/modules/test.ts

import {
  getModule,
  Module,
  VuexModule,
  Mutation,
  Action,
} from 'vuex-module-decorators'
import store from '../index'
import { api } from '../../utils/axios'

type TestType = {
  id: number
  name: string
  description: string
}

type TestState = {
  apiTests: TestType[]
}

@Module({ store, dynamic: true, namespaced: true, name: 'Test' })
class TestModule extends VuexModule implements TestState {
  apiTests: TestType[] = []

  @Mutation
  SET_API_TESTS(payload: TestType[]) {
    this.apiTests = payload
  }
  @Action
  async getTests() {
    const response = await api.get('/tests')

    if (response.data.data) {
      this.SET_API_TESTS(response.data.data)
    }
  }
}

export const testModule = getModule(TestModule)

Erstellen Sie einen Vuex-Testspeicher und speichern Sie die Daten, die durch Aufrufen der in GetTests of Action erstellten API im Status apiTests erhalten wurden.

app/src/pages/Test.vue


<template>
  <div class="test">
    <v-data-table :headers="headers" :items="tests"> </v-data-table>
  </div>
</template>

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import { testModule } from '../store/modules/test'

@Component
export default class Test extends Vue {
  tests = []

  headers = [
    { text: 'ID', align: 'center', value: 'id' },
    { text: 'Name', align: 'center', value: 'name' },
    { text: 'Einzelheiten', align: 'center', value: 'description' },
  ]

  async created() {
    await testModule.getTests()

    this.tests = testModule.apiTests
  }
}
</script>

Führen Sie beim Erstellen des Vue die Aktion getTests im Testspeicher aus, um die Daten abzurufen, und binden Sie die apiTests-Daten, um auf die Daten im Vue zu verweisen. Übergeben Sie die Daten an die V-Tabelle von Vuetify und Sie sind fertig.

Bestätigung!

localhost:8080

スクリーンショット 2020-09-22 2.49.52.png

Bisher konnte ich die API auf der Vorderseite aufrufen, die Daten aus der Datenbank abrufen, die zurückgegebenen Daten in Vuex speichern und rendern. Nachdem Sie eine Basis haben, können Sie diese erweitern, indem Sie APIs und Seiten auf dieselbe Weise hinzufügen.

Nachdem die Vorlage vollständig ist, werde ich eine App erstellen, mit der Sie beim nächsten Mal einfache CLUD-Operationen ausführen können!

nächstes Mal

  • Separat erstellen

Referenz

Erstellen einer Umgebung für [TypeScript + Vue + Express + MySQL] mit Docker ~ Vue Edition ~ Erstellen einer Umgebung von [TypeScript + Vue + Express + MySQL] mit Docker ~ MySQL Edition ~ Erstellen einer Umgebung von [TypeScript + Vue + Express + MySQL] mit Docker ~ Express ~

Recommended Posts

So erstellen Sie mit Docker ~ Sequelize ~ eine [TypeScript + Vue + Express + MySQL] -Umgebung
So erstellen Sie mit Docker ~ Express ~ eine [TypeScript + Vue + Express + MySQL] -Umgebung
So erstellen Sie mit Docker ~ MySQL ~ eine [TypeScript + Vue + Express + MySQL] -Umgebung
So erstellen Sie mit Docker ~ Vue ~ eine [TypeScript + Vue + Express + MySQL] -Umgebung
So erstellen Sie eine Rails + Vue + MySQL-Umgebung mit Docker [neueste Version 2020/09]
So erstellen Sie eine Rails 6-Umgebung mit Docker
[Rails] So erstellen Sie eine Umgebung mit Docker
[Road_node.js_1-1] Der Weg zum Erstellen der Node.js Express MySQL-Umgebung mit Docker
So erstellen Sie eine Docker-Umgebung mit Gradle for IntelliJ
So erstellen Sie eine Ruby on Rails-Entwicklungsumgebung mit Docker (Rails 6.x)
So erstellen Sie eine Ruby on Rails-Entwicklungsumgebung mit Docker (Rails 5.x)
[Docker-Umgebung] Umgang mit ActiveSupport :: MessageEncryptor :: InvalidMessage
Build Rails (API) x MySQL x Nuxt.js Umgebung mit Docker
[Rails] [Docker] Kopieren und Einfügen ist in Ordnung! So erstellen Sie eine Rails-Entwicklungsumgebung mit Docker
So beenden Sie Docker für Mac und erstellen eine Docker-Entwicklungsumgebung mit Ubuntu + Vagrant
Erstellen Sie mit Docker eine Vue3-Umgebung!
Erstellen Sie mit Docker eine lokale Couchbase-Umgebung
Erstellen Sie mit Docker eine Node.js-Umgebung
[Umgebungskonstruktion mit Docker] Rails 6 & MySQL 8
Aktualisieren Sie MySQL mit Docker von 5.7 auf 8.0
Erstellen Sie mit Laradock eine Docker + Laravel-Umgebung
So erstellen Sie CloudStack mit Docker
So starten Sie Camunda mit Docker
Ich habe versucht, mit Docker eine Plant UML Server-Umgebung zu erstellen
So installieren Sie Pry nach dem Erstellen einer Rails-Entwicklungsumgebung mit Docker
Erstellen Sie mit Docker Compose eine Entwicklungsumgebung für Django + MySQL + nginx
So teilen Sie Dateien mit Docker Toolbox
Erstellen Sie mit Docker eine PureScript-Entwicklungsumgebung
Mit Docker auf Heroku bereitstellen (Rails 6, MySQL)
Bearbeiten Sie MySQL mit Befehlen in der Docker-Umgebung
[Docker] Erstellen Sie mit Docker eine Node.js + Express + Webpack-Umgebung
Erstellen einer Umgebung für Laravel + MySQL + phpMyadmin mit Docker
Erstellen Sie mit Docker eine Wordpress-Entwicklungsumgebung
Erstellen Sie eine Nuxt TypeScript + Vuetify-Umgebung mit Docker-Compose
[Docker] Erstellen Sie die Ausführungsumgebung von Jupyter Lab mit Docker
Erstellen Sie eine Umgebung mit Docker unter AWS
Erstellen Sie mit Docker eine TensorFlow-Betriebsüberprüfungsumgebung
So führen Sie Blazor (C #) mit Docker aus
Ausführen mit normalen Befehlen für die Entwicklungssprache in der Docker-Entwicklungsumgebung
01. Ich habe versucht, eine Umgebung mit SpringBoot + IntelliJ + MySQL (MyBatis) (Windows 10) zu erstellen.
Als ich versuchte, mit Docker eine Umgebung für PHP7.4 + Apache + MySQL zu erstellen, blieb ich stecken [Windows & Mac]
So verknüpfen Sie Rails6 Vue (aus dem Umgebungsbau)
Erstellen Sie eine Laravel / Docker-Umgebung mit VSCode devcontainer
So geben Sie jemandem Ihr Image mit Docker
Versuchen Sie, Express + PostgreSQL + Sequelize mit Docker zu erstellen [Teil 1]