我在理解使用 Ktor 的 DSL 进行请求路由的正确方法时遇到了一些麻烦。问题是,当我测试我的 API 并尝试GET /nomenclature/articles/categories
返回所有文章类别的列表时,我得到的是当参数无效时我为路由Invalid article specified
返回的消息。/nomenclature/articles/{articleId}
articleId
这是我的代码:
route("/nomenclature") {
method(HttpMethod.Get) {
handle { call.respondText("The resource you accessed is not a valid REST resource, but a parent node. Children nodes include articles, categories, subcategories and so on.") }
}
route("articles") {
route("categories") {
get("{categoryId?}") {
val categoryIdParam = call.parameters["categoryId"]
if (categoryIdParam != null) {
val categoryId = categoryIdParam.toIntOrNull()
if (categoryId != null) {
val category = articlesDAO.findCategoryById(categoryId)
if (category != null) call.respond(category)
else call.respondText("Category not found", status = HttpStatusCode.NotFound)
} else call.respondText("Invalid category ID specified", status = HttpStatusCode.BadRequest)
} else {
val categories = articlesDAO.getCategories()
if (categories != null) call.respond(categories)
else call.respondText("No categories found", status = HttpStatusCode.NotFound)
}
}
}
route("subcategories") {
get("{subcategoryId?}") {
val subcategoryIdParam = call.parameters["subcategoryId"]
if (subcategoryIdParam != null) {
val subcategoryId = subcategoryIdParam.toIntOrNull()
if (subcategoryId != null) {
val subcategory = articlesDAO.findSubcategoryById(subcategoryId)
if (subcategory != null) call.respond(subcategory)
else call.respondText("Subcategory not found", status = HttpStatusCode.NotFound)
} else call.respondText("Invalid subcategory ID specified", status = HttpStatusCode.BadRequest)
} else {
val subcategories = articlesDAO.getCategories()
if (subcategories != null) call.respond(subcategories)
else call.respondText("No subcategories found", status = HttpStatusCode.NotFound)
}
}
}
get("types") {
val articleTypes = articlesDAO.getArticleTypes()
if (articleTypes != null) call.respond(articleTypes)
else call.respondText("No article types found", status = HttpStatusCode.NotFound)
}
get("wholePackagings") {
val wholePackagings = articlesDAO.getWholePackagings()
if (wholePackagings != null) call.respond(wholePackagings)
else call.respondText("No whole packagings found", status = HttpStatusCode.NotFound)
}
get("fractionsPackagings") {
val fractionsPackagings = articlesDAO.getFractionPackagings()
if (fractionsPackagings != null) call.respond(fractionsPackagings)
else call.respondText("No fractions packagings found", status = HttpStatusCode.NotFound)
}
get("{articleId?}") {
val articleIdParam = call.parameters["articleId"]
if (articleIdParam != null) {
val articleId = articleIdParam.toIntOrNull()
if (articleId != null) {
val article = articlesDAO.findArticleById(articleId)
if (article != null) call.respond(article) else call.respondText("No article found", status = HttpStatusCode.NotFound)
} else call.respondText("Invalid article ID specified", status = HttpStatusCode.BadRequest)
} else {
val articles = articlesDAO.getArticles()
if (articles != null) call.respond(articles) else call.respondText("No articles found", status = HttpStatusCode.NotFound)
}
}
}
}
如果有人可以通过提供一个基本但比较全面的示例来帮助我,说明如何使用所有 Ktor 路由匹配器和处理程序(包括以嵌套资源方式),那将是非常棒的。
编辑:我已经使用不同的方法重写了路由,但我仍然想知道为什么我以前的版本没有按预期工作。这是我的第二种方法,似乎可以按预期工作(我已经测试过了):
routing {
route("/v1") {
route("stock") {
get {
val stock = stockDAO.getAllStock()
if (stock != null) call.respond(stock) else call.respondText("No stock found", status = HttpStatusCode.NotFound)
}
get("{locationId}") {
val locationIdParam = call.parameters["locationId"]
if (locationIdParam != null) {
val locationId = locationIdParam.toIntOrNull()
if (locationId != null) {
val stock = stockDAO.getStockByLocationId(locationId)
if (stock != null) call.respond(stock) else call.respondText("No stock found", status = HttpStatusCode.NotFound)
} else call.respondText("ERROR: Invalid location ID specified.", status = HttpStatusCode.BadRequest)
}
}
}
route("nomenclature") {
get {
call.respondText("The resource you accessed is not a valid REST resource, but a parent node. Children nodes include articles, categories, subcategories and so on.")
}
route("articles") {
get {
val articles = articlesDAO.getArticles()
if (articles != null) call.respond(articles) else call.respondText("No articles found", status = HttpStatusCode.NotFound)
}
get("{articleId}") {
val articleIdParam = call.parameters["articleId"]
if (articleIdParam != null) {
val articleId = articleIdParam.toIntOrNull()
if (articleId != null) {
val article = articlesDAO.findArticleById(articleId)
if (article != null) call.respond(article) else call.respondText("No article found", status = HttpStatusCode.NotFound)
} else call.respondText("Invalid article ID specified", status = HttpStatusCode.BadRequest)
}
}
route("categories") {
get {
val categories = articlesDAO.getCategories()
if (categories != null) call.respond(categories)
else call.respondText("No categories found", status = HttpStatusCode.NotFound)
}
get("{categoryId}") {
val categoryIdParam = call.parameters["categoryId"]
if (categoryIdParam != null) {
val categoryId = categoryIdParam.toIntOrNull()
if (categoryId != null) {
val category = articlesDAO.findCategoryById(categoryId)
if (category != null) call.respond(category)
else call.respondText("Category not found", status = HttpStatusCode.NotFound)
} else call.respondText("Invalid category ID specified", status = HttpStatusCode.BadRequest)
}
}
}
route("subcategories") {
get {
val subcategories = articlesDAO.getSubcategories()
if (subcategories != null) call.respond(subcategories)
else call.respondText("No subcategories found", status = HttpStatusCode.NotFound)
}
get("{subcategoryId}") {
val subcategoryIdParam = call.parameters["subcategoryId"]
if (subcategoryIdParam != null) {
val subcategoryId = subcategoryIdParam.toIntOrNull()
if (subcategoryId != null) {
val subcategory = articlesDAO.findSubcategoryById(subcategoryId)
if (subcategory != null) call.respond(subcategory)
else call.respondText("Subcategory not found", status = HttpStatusCode.NotFound)
} else call.respondText("Invalid subcategory ID specified", status = HttpStatusCode.BadRequest)
}
}
}
get("types") {
val articleTypes = articlesDAO.getArticleTypes()
if (articleTypes != null) call.respond(articleTypes)
else call.respondText("No article types found", status = HttpStatusCode.NotFound)
}
get("wholePackagings") {
val wholePackagings = articlesDAO.getWholePackagings()
if (wholePackagings != null) call.respond(wholePackagings)
else call.respondText("No whole packagings found", status = HttpStatusCode.NotFound)
}
get("fractionsPackagings") {
val fractionsPackagings = articlesDAO.getFractionPackagings()
if (fractionsPackagings != null) call.respond(fractionsPackagings)
else call.respondText("No fractions packagings found", status = HttpStatusCode.NotFound)
}
}
}
}
}