Open KeihakuOh opened 2 weeks ago
catch(err) は、拒否(reject)された Promise をキャッチして処理するためのメソッド
import mongoose from 'mongoose';
import express, { Request, Response } from 'express';
import { requireAuth, validateRequest } from '@wsbticket/common/build';
import { body } from 'express-validator';
const router = express.Router();
router.post(
'/api/orders',
requireAuth,
[
body('ticketId')
.not()
.isEmpty()
.custom((input: string) => mongoose.Types.ObjectId.isValid(input))
.withMessage('TicketId must be provided'),
],
validateRequest,
async (req: Request, res: Response) => {
res.send({});
}
);
export { router as newOrderRouter };
import { Request, Response, NextFunction } from "express";
import { validationResult } from "express-validator";
import { RequestValidationError } from "../errors/request-validation-error";
export const validateRequest = (
req: Request,
res: Response,
next: NextFunction
) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
throw new RequestValidationError(errors.array());
}
next();
};
[ body('ticketId') .not() .isEmpty() .custom((input: string) => mongoose.Types.ObjectId.isValid(input)) .withMessage('TicketId must be provided'), ], validateRequest,
[ body('ticketId') .not() .isEmpty() .custom((input: string) => mongoose.Types.ObjectId.isValid(input)) .withMessage('TicketId must be provided'), ],はバリデーションを追加して、実際判断するのはvalidateRequestのvalidationResult(req)
import mongoose from 'mongoose';
interface OrderAttrs {
userId: string;
status: string;
expiresAt: Date;
ticket: TicketDoc;
}
interface OrderDoc extends mongoose.Document {
userId: string;
status: string;
expiresAt: Date;
ticket: TicketDoc;
}
interface OrderModel extends mongoose.Model<OrderDoc> {
build(attrs: OrderAttrs): OrderDoc;
}
const orderSchema = new mongoose.Schema(
{
userId: {
type: String,
required: true,
},
status: {
type: String,
required: true,
},
expiresAt: {
type: mongoose.Schema.Types.Date,
},
ticket: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Ticket',
},
},
{
toJSON: {
transform(doc, ret) {
ret.id = ret._id;
delete ret._id;
},
},
}
);
orderSchema.statics.build = (attrs: OrderAttrs) => {
return new Order(attrs);
};
const Order = mongoose.model<OrderDoc, OrderModel>('Order', orderSchema);
export { Order };
TicketDoc: データベースに保存されたチケットを操作するときに使う。Mongooseが自動的に追加するフィールド(_id、createdAt、updatedAtなど)も含まれるため、これらの情報を扱うことができる
TicketDoc: データベースに保存されたチケットを操作するときに使う。Mongooseが自動的に追加するフィールド(_id、createdAt、updatedAtなど)も含まれるため、これらの情報を扱うことができる
const Order = mongoose.model<OrderDoc, OrderModel>('Order', orderSchema);がないとorderSchema.statics.build = (attrs: OrderAttrs) => { return new Order(attrs); };はエラーになる
enum
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
let currentDirection: Direction = Direction.Up;
console.log(currentDirection); // 出力: "UP"
if (currentDirection === Direction.Up) {
console.log("Going up!");
}
const orderSchema = new mongoose.Schema(
{
userId: {
type: String,
required: true,
},
status: {
type: String,
required: true,
},
expiresAt: {
type: mongoose.Schema.Types.Date,
},
ticket: {
type: mongoose.Schema.Types.ObjectId, // 他のコレクションのドキュメントを参照するための ObjectId 型
ref: 'Ticket', // Ticket コレクションを参照
},
},
{
toJSON: {
transform(doc, ret) {
ret.id = ret._id;
delete ret._id;
},
},
}
);
ticket: { type: mongoose.Schema.Types.ObjectId, // 他のコレクションのドキュメントを参照するための ObjectId 型 ref: 'Ticket', // Ticket コレクションを参照 }, Ticketのidだけ保存して、それを使って関連付けしている
import mongoose from 'mongoose';
import { Order, OrderStatus } from './order';
interface TicketAttrs {
title: string;
price: number;
}
export interface TicketDoc extends mongoose.Document {
title: string;
price: number;
isReserved(): Promise<boolean>;
}
interface TicketModel extends mongoose.Model<TicketDoc> {
build(attrs: TicketAttrs): TicketDoc;
}
const ticketSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
min: 0,
},
},
{
toJSON: {
transform(doc, ret) {
ret.id = ret._id;
delete ret._id;
},
},
}
);
ticketSchema.statics.build = (attrs: TicketAttrs) => {
return new Ticket(attrs);
};
ticketSchema.methods.isReserved = async function () {
// this === the ticket document that we just called 'isReserved' on
const existingOrder = await Order.findOne({
ticket: this,
status: {
$in: [
OrderStatus.Created,
OrderStatus.AwaitingPayment,
OrderStatus.Complete,
],
},
});
return !!existingOrder;
};
const Ticket = mongoose.model<TicketDoc, TicketModel>('Ticket', ticketSchema);
export { Ticket };
isReserved() が個々のチケットドキュメント(TicketDoc)に対して動作するインスタンスメソッドだから ・モデルは MongoDB のコレクション全体に対する操作を行うクラスのようなもの ・ドキュメントは、MongoDB のコレクション内の個々のレコードに対応するオブジェクト
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; 目的: HTTPSリクエストの際に、自己署名証明書や信頼されていない証明書を許可するように設定
orders コレクション(注文)
{
"_id": "order1",
"userId": "user1",
"ticket": "ticket1"
}
tickets コレクション(チケット):
{
"_id": "ticket1",
"title": "Concert A",
"price": 100
}
const orders = await Order.find({
userId: req.currentUser!.id, // 現在のユーザーの注文を取得
}).populate('ticket'); // 'ticket' フィールドをポピュレート
結果:
{
"_id": "order1",
"userId": "user1",
"ticket": {
"_id": "ticket1",
"title": "Concert A",
"price": 100
}
}
import mongoose from 'mongoose';
import { Order, OrderStatus } from './order';
interface TicketAttrs {
title: string;
price: number;
}
export interface TicketDoc extends mongoose.Document {
title: string;
price: number;
isReserved(): Promise<boolean>;
}
interface TicketModel extends mongoose.Model<TicketDoc> {
build(attrs: TicketAttrs): TicketDoc;
}
const ticketSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
min: 0,
},
},
{
toJSON: {
transform(doc, ret) {
ret.id = ret._id;
delete ret._id;
},
},
}
);
ticketSchema.statics.build = (attrs: TicketAttrs) => {
return new Ticket(attrs);
};
ticketSchema.methods.isReserved = async function () {
// this === the ticket document that we just called 'isReserved' on
const existingOrder = await Order.findOne({
ticket: this,
status: {
$in: [
OrderStatus.Created,
OrderStatus.AwaitingPayment,
OrderStatus.Complete,
],
},
});
return !!existingOrder;
};
const Ticket = mongoose.model<TicketDoc, TicketModel>('Ticket', ticketSchema);
export { Ticket };
TicketAttrsはbuild用のインタフェース、TicketDoc, TicketModeはモデル側の、'Ticket'はコレクション(SQL側のデータベース)
Ticketモデルを使ってドキュメントを初めて保存しようとすると、MongoDBは自動的にticketsという名前のコレクションを作成します(モデル名がTicketなので、その複数形の小文字であるticketsがデフォルトのコレクション名)(MongoDBの「コレクション」は、SQLデータベースの「テーブル」に相当する)