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.
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 ~
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.
$ docker-compose up -d
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.
$ docker exec -it api_container sh
$ 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}!`))
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.
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
Zugriff auf localhost: 3000 / api / tests! Es ist in Ordnung, wenn die tatsächlichen Daten in JSON zurückgegeben werden!
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.
Zugriff auf localhost: 3000 / api / tests / 1
Wenn die Daten von / tests / ** {hier angegebene ID} ** zurückgegeben werden, ist dies erfolgreich! Bitte überprüfen Sie mit anderen IDs als Test.
Zu diesem Zeitpunkt ist die Serverseite abgeschlossen. Von hier aus nehmen wir Einstellungen vor, um die erstellte API tatsächlich von vorne aufzurufen.
$ exit
$ docker exec -it app_container sh
$ 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.
localhost:8080
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!
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