Reputation: 9
When sending a POST request to register a user using Postman, a 404 Not Found error is encountered. The Ktor server logs indicate a failure in resolving routes with the message: "No matched subtrees found."
Trace Output:
TRACE io.ktor.routing.Routing - Trace for [v1, users, register]
/, segment:0 -> SUCCESS @ /
/, segment:0 -> SUCCESS @ /
/(method:GET), segment:0 -> FAILURE "Selector didn't match" @ /(method:GET)
/(method:POST), segment:0 -> FAILURE "Not all segments matched" @ /(method:POST)
Matched routes:
No results
Route resolve result:
FAILURE "No matched subtrees found" @ /
TRACE i.k.s.p.c.ContentNegotiation - Skipping response body transformation from HttpStatusCode to OutgoingContent for the POST /v1/users/register request because the HttpStatusCode type is ignored. See [ContentNegotiationConfig::ignoreType].
Additional Information: Endpoint Structure:
The project involves user authentication and note-related functionality. Endpoints include registration (/v1/users/register) and note operations (/v1/notes/create, /v1/notes/update, /v1/notes/delete). Routing Setup:
Routes are configured using the Ktor routing mechanism in multiple files (UserRoutes.kt, NoteRoutes.kt). The routes include authentication using JWT. Content Negotiation Issue:
The trace indicates a content negotiation issue: "Skipping response body transformation from HttpStatusCode to OutgoingContent." Potential Causes:
Mismatch in Accept headers in the request. Content type configuration in the application might be affecting negotiation. Ignoring HttpStatusCode type in content negotiation.
UserRoutes.kt:
package com.example.routes
import com.example.authentication.Jwt_Service
import com.example.data.model.LoginRequest
import com.example.data.model.RegistrationRequest
import com.example.data.model.SimpleResponse
import com.example.data.model.Userdata
import com.example.repository.repo
import io.ktor.http.*
import io.ktor.resources.*
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
const val API_VERSION = "v1"
const val USERS = "$API_VERSION/users"
const val REGISTER = "$USERS/register"
const val LOGIN = "$USERS/login"
@Resource(REGISTER)
class Registration
@Resource(LOGIN)
class Login
fun Route.UserRoutes(db: repo, jwtService: Jwt_Service, hash: (String) -> String){
post<Registration> {
val register_request = try {
call.receive<RegistrationRequest>()
}catch (e:Exception){
call.respond(HttpStatusCode.BadRequest, SimpleResponse(false,"Missing some fields"))
return@post
}
try {
val user = Userdata(register_request.email,register_request.name,register_request.password)
db.addUser(user)
call.respond(HttpStatusCode.OK,SimpleResponse(success = true,jwtService.generateToken(user)))
}catch (e:Exception){
call.respond(HttpStatusCode.Conflict,SimpleResponse(success = false,"Some error occured!"))
}
}
//similar method for login
The project have a similar file for defining NoteRoutes as well where the concept of Authentication is also implemented
Authentication:
fun Application.configureAuthentication(){
log.info("Authentication started")
val jwtService = Jwt_Service()
val db = repo()
install(Authentication){
jwt("jwt"){
verifier(jwtService.verifier)
realm = "Notify Server"
validate {
val payload = it.payload
val email = payload.getClaim("email").asString()
val user = db.findUser(email)
user
}
}
}
Data class for User is defined as:
@Serializable
data class Userdata(
val email: String,
val name: String,
val hashpassword: String
):Principal
cURL version of postman request:
curl --location 'localhost:8080/v1/users/register' \
--header 'Content-Type: application/json' \
--data-raw '{
"email":"[email protected]",
"name":"ayush",
"password":"bvdsjc"
}'
Upvotes: 0
Views: 363