使用Node.js + Express + TypeScript创建WebAPI(3/4)
概述
-
- メモ的な書き残し
-
- MongoDBと接続してデータの取得をやってみる
- セキュリティ云々は考えていません
请提供以下内容的中文释义,只需要一种选项:
参考
[Node.js] 用 TypeScript 编写 Express – MongoDB 连接篇
我感激地参考了这个。
连接到MongoDB
从这一带开始进入未知领域。将会通过官方渠道进行调查和探索。首先需要安装可能会用到的东西。
npm install --save-dev @types/mongoose @types/jsonwebtoken
这里是关于如何使用库的方式
Mongoose v5.4.0
MongoDB v3.x
MongoDB的使用方法在这里。
Mongo Shell
import * as mongoose from "mongoose";
const uri = "mongodb://localhost:27017";
const dbName = "js-web-api";
mongoose.connect(uri + "/" + dbName, (e) => {
console.log(e);
});
仅需要一个选项,以下是mongoose的最小配置。我们首先准备一个数据库。数据库名称是“js-web-api”,集合名称是“users”。
> mongo
> show dbs
any dbs
> use js-web-api
switched to db js-web-api
> db.createCollection('users');
{ "ok" : 1 }
> show collections
users
> exit
用mongoDB重新配置DB连接。顺便让它具备通用性。
// ./src/dbClient.ts
import mongoDB from "mongodb";
const url = "mongodb://localhost:27017";
export const dbName = "js-web-api";
export default (callback: (err: mongoDB.MongoError, client: mongoDB.MongoClient, db: mongoDB.Db) => void) => {
const client = mongoDB.MongoClient;
client.connect(url, { useNewUrlParser: true }, (err, db) => {
if (err) { throw err; }
callback(err, db, db.db(dbName));
});
};
我会这样使用。
dbClient((err, client) => {
if (err) {
client.close();
return;
}
// 何か処理する
client.close();
});
我会创建一个用于连接测试的ts文件。
// ./src/routes/test/index.ts
import express from "express";
import mongodbClient from "../../dbClient";
const router = express.Router();
router.get("/dbConnect", (req, res, next) => {
mongodbClient((err, client) => {
if (err) {
res.status(500).json({
msg: ":-(",
});
return next(err);
}
res.json({
msg: ":-)",
});
client.close();
});
});
export default router;
在server.ts文件中进行分配并启动服务器,然后在localhost:3000/test/dbConnect上进行GET请求即可获得响应。
// ./src/server.ts
// 差分だけ記述
import test from "./routes/test/index";
app.use("/test", test);
> npm run ts-node ./src/server.ts
> url localhost:3000/test/dbConnect
{"msg":":-)"}
由于cURL很方便,所以让自己学会使用吧。虽然选项很多,我自己也有些不清楚。如果在打开终端时感到不安,可以尝试使用Postman等工具。现在数据库连接已经完成,接下来将从集合中获取数据。首先,在数据库的(js-web-api)集合(users)中添加文档。我们要对uid应用唯一约束。以下是日志记录。
> mongo
> use js-web-api
switched to db js-web-api
> db
js-web-api
> show collections
users
> db.users.insert({uid:"1",name:"hoge",password:"piyo"})
WriteResult({ "nInserted" : 1 })
> db.users.find()
{ "_id" : ObjectId("5c20ede66b9d3f8aefd9112a"), "uid" : "1", "name" : "hoge", "password" : "piyo" }
> db.users.createIndex({uid:1},{unique:true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.users.insert({uid:"1",name:"hogehoge",pass
word: "piyopiyo"})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: js-web-api.users index: uid_1 dup key: { : \"1\" }"
}
})
> db.users.insert({uid:"2",name:"hogehoge",pass
word: "piyopiyo"})
WriteResult({ "nInserted" : 1 })
> db.users.find()
{ "_id" : ObjectId("5c20ede66b9d3f8aefd9112a"), "uid" : "1", "name" : "hoge", "password" : "piyo" }
{ "_id" : ObjectId("5c20f3596b9d3f8aefd9112c"), "uid" : "2", "name" : "hogehoge", "password" : "piyopiyo" }
> exit
接下来我们将定义一个名为document的变量。
// ./src/documents/IDocumentUser.ts
import * as MongoDB from "mongodb";
export interface IDocumentUser {
_id: MongoDB.ObjectId;
uid: string;
name: string;
password: string;
}
由于当前状况下request.body未定义,所以我们将进行相应的处理。另外,如果被调用了未定义的URL,我们将返回404错误。虽然可能会偏离主题,但无所谓。
// ./src/server.ts
import bodyParser from "body-parser";
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use((req, res) => {
res.status(404);
res.json({
message: "API Not Found",
requestPath: req.path,
});
});
请注意,如果将返回404的处理程序写在路由处理程序之后,无论访问哪个页面都会返回404错误。实际上,情况如下所示:
app.use("/auth", auth);
app.use("/users", users);
app.use("/test", test);
app.use((req, res) => {
res.status(404);
res.json({
message: "API Not Found",
requestPath: req.path,
});
});
目前为止,已经完成了与数据库的连接。作为这篇文章的最后一部分,我们将尝试使用先前创建的接口从数据库中获取数据。
// ./src/routes/users/index.ts
import express from "express";
import mongodbClient from "../../dbClient";
import IDocumentUser from "../../documents/IdocumentUser";
import noImpl from "../../noImpl";
const router = express.Router();
router.post("/signup", noImpl);
router.put("/:user", noImpl);
router.delete("/:user", noImpl);
router.get("/:user", (req, res, next) => {
const uid = req.params.user;
mongodbClient((ce, client, db) => {
if (ce) {
client.close();
res.status(500);
res.json({
message: ce.message,
requestPath: req.path,
});
return next(ce);
}
const collection = db.collection<IDocumentUser>("users");
collection.findOne({ uid: String }, (e, result) => {
if (e) {
client.close();
res.status(500);
res.json({
message: e.message,
requestPath: req.path,
});
return next(e);
}
client.close();
if (result === null) {
res.status(404).json({
message: "Not Found.",
});
}
res.json(result);
});
});
});
export default router;
> curl localhost:3000/users/1
{"_id":"5c20ede66b9d3f8aefd9112a","uid":"1","name":"hoge","password":"piyo"}
暂时先实现Get功能吧。虽然我想要在认证之后实现Get,但现在先按照数据库连接的流程来创建它。等认证相关的实现后,再继续进行Post/Put/Delete操作。