#node.js #typescript #express
#node.js #машинописный текст #экспресс
Вопрос:
Приложение компилируется без ошибок и сообщает, что сервер запускается с правильного порта. Однако, когда я перехожу к любому из моих зарегистрированных маршрутов, я получаю сообщение об ошибке «не удается получить доступ к этому маршруту».
Я не нашел много информации о Express с классами, особенно о части маршрутизатора. Из console.log(controller.router)
переменной маршрутизатора это кажется правильным, путь, отсутствующий в нем, странный, но я предполагаю, что регулярное выражение просто занимает место вместо этого.
В this.router
экземпляре также нет метода path, поэтому я не уверен, как еще указать путь, отличный от get(path, handler)
.
console.log(`/v1${controller.basePath}`, controller.router):
""""
/v1/users [Function: router] {
params: {},
_params: [],
caseSensitive: undefined,
mergeParams: undefined,
strict: undefined,
stack: [
Layer {
handle: [Function: bound dispatch],
name: 'bound dispatch',
params: undefined,
path: undefined,
keys: [],
regexp: /^/users/?$/i,
route: [Route]
},
Layer {
handle: [Function: bound dispatch],
name: 'bound dispatch',
params: undefined,
path: undefined,
keys: [],
regexp: /^/users/?$/i,
route: [Route]
},
Layer {
handle: [Function: bound dispatch],
name: 'bound dispatch',
params: undefined,
path: undefined,
keys: [Array],
regexp: /^/users/(?:([^/] ?))/?$/i,
route: [Route]
},
Layer {
handle: [Function: bound dispatch],
name: 'bound dispatch',
params: undefined,
path: undefined,
keys: [Array],
regexp: /^/users/(?:([^/] ?))/?$/i,
route: [Route]
}
]
}
"""
Я также пробовал с localhost:1337/v1/users/
just incase, но происходит то же самое.
Я не понимаю, что может быть не так, заранее спасибо за помощь!
Класс приложения
import * as express from "express"
import * as mongoose from "mongoose"
import * as bodyParser from "body-parser"
mongoose.connect("mongodb://localhost:27017/socketpro", {
useUnifiedTopology: true,
useNewUrlParser: true,
useCreateIndex: true,
})
class App {
public port: number
public app: express.Application
private controllers: any
constructor(controllers: any, port: number) {
this.port = port
this.controllers = controllers
this.app = express()
this.initializeMiddlewares()
this.initializeControllers()
}
private initializeMiddlewares() {
this.app.use(bodyParser.json())
}
private initializeControllers() {
this.controllers.forEach((controller: any) => {
console.log(`/v1${controller.basePath}`, controller.router)
this.app.use(`/v1${controller.basePath}`, controller.router)
})
}
public listen() {
this.app.listen(this.port, () => {
console.log(`App listening on the port ${this.port}`)
})
}
}
export default App
Пользовательский контроллер
import { UserModel as User, UserInterface } from "../Utils/User"
import { Router, Request, Response } from "express"
export default class UsersController {
[x: string]: any
public basePath = "/users"
public router: Router = null
private posts: UserInterface[] = []
constructor() {
this.router = Router()
this.intializeRoutes()
}
public intializeRoutes() {
let routes = [
{
path: "/",
method: "get",
function: "GetUsers",
},
{
path: "/",
method: "post",
function: "CreateUser",
},
{
path: "/:id",
method: "get",
function: "GetUser",
},
{
path: "/:id",
method: "post",
function: "UpdateUser",
},
]
routes.map((route) => {
let path = `${this.basePath}${route.path ?? ""}`
switch (route.method) {
case "get":
this.router.get(path, this[route.function])
break
case "post":
this.router.post(path, this[route.function])
break
}
})
}
async GetUser(request: Request, response: Response) {
let userId: string = request.params.id
let user = await User.findOne({
_id: userId,
})
response.send({
user,
})
}
async GetUsers(request: Request, response: Response) {
response.send({status: true})
}
async CreateUser(request: Request, response: Response) {
let user: UserInterface = new User(request.body)
user = await user.save()
response.send(user)
}
async UpdateUser(request: Request, response: Response) {
let body: UserInterface = request.body
await User.updateOne(
{
_id: request.params.id,
},
body
).exec()
response.send({
status: true,
})
}
}
Репозиторий кода:https://github.com/Rusherz/express-router-class
Комментарии:
1. Непонятно, о чем вы спрашиваете. Можете ли вы показать нам свой код и описать конкретную проблему с вашим кодом? Код, необходимый для понимания вопроса, ДОЛЖЕН быть вставлен в сам вопрос, а не доступен только как внешняя ссылка. Это рекомендации stackoverflow, и существует целая куча веских причин, по которым требуется, чтобы вопросы были написаны таким образом. Пожалуйста, включите соответствующий код для вопроса В сам вопрос, отформатированный соответствующим образом как код. Вы можете оставить внешнюю ссылку на остальную часть репозитория, но это не должно быть единственной ссылкой на код.
2. Я обновил вопрос, пожалуйста, дайте мне знать, если он станет более понятным. Также извините за код, казалось, что лучше просто предоставить всю базу кода, потому что я не полностью использую, если фактическая проблема заключается. Но я добавил соответствующий код, который, по моему мнению, является.
3. Вы создаете объект Router и добавляете к нему маршруты, но что вам делать
app.use(path, router)
с объектом router, чтобы фактически подключить маршрутизатор к вашему серверу?4. К вашему сведению, указание имен функций маршрута с помощью строки в вашей таблице немного странно. Почему бы просто напрямую не ссылаться на сами методы?
5. Замечание. Вы создали свою собственную абстракцию для многих вещей, которые выполняет Express, и в процессе очень затруднили понимание вашего кода тем, кто знаком с Express. Я не уверен, что вы делаете что-то проще, просто создавая свой собственный внутренний API, который больше никто не узнает. Вы могли бы использовать интерфейс express и расширить его, а не скрывать / заменять, чтобы добавить свои собственные возможности (если чего-то не хватает), и тогда это не показалось бы чуждым разработчику Express.
Ответ №1:
Проблема с моим кодом заключалась в области видимости, или в том, что я считаю областью видимости.
Я нашел сообщение, на котором основывал это,https://dev.to/aligoren/developing-an-express-application-using-typescript-3b1
Проблема с кодом заключается в файлах контроллера, у меня был
async GetUser(request: Request, response: Response) {
let userId: string = request.params.id
let user = await User.findOne({
_id: userId,
})
response.send({
user,
})
}
Вместо:
GetUser = async (request: Request, response: Response) => {
let userId: string = request.params.id
let user = await User.findOne({
_id: userId,
})
response.send({
user,
})
}
Другим решением было бы изменить:
switch (route.method) {
case "get":
this.router.get(path, this[route.function])
break
case "post":
this.router.post(path, this[route.function])
break
}
Для:
switch (route.method) {
case "get":
this.router.get(path, this[route.function].bind(this))
break
case "post":
this.router.post(path, this[route.function].bind(this))
break
}
Просто на случай, если у кого-то возникнет похожая проблема со мной в будущем.