move routes installation into component

This commit is contained in:
2021-01-21 21:55:24 +01:00
parent 3ba4a195ba
commit 667339979b
27 changed files with 492 additions and 420 deletions

View File

@@ -7,28 +7,15 @@ import com.fasterxml.jackson.databind.PropertyNamingStrategy
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.datatype.joda.JodaModule
import com.github.jasync.sql.db.postgresql.exceptions.GenericDatabaseException
import component.auth.jwt.jwtInstallation
import fr.dcproject.application.Env.PROD
import fr.dcproject.component.article.routes.findArticleVersions
import fr.dcproject.component.article.routes.findArticles
import fr.dcproject.component.article.routes.getOneArticle
import fr.dcproject.component.article.routes.upsertArticle
import fr.dcproject.component.article.routes.installArticleRoutes
import fr.dcproject.component.auth.ForbiddenException
import fr.dcproject.component.auth.routes.authLogin
import fr.dcproject.component.auth.routes.authPasswordless
import fr.dcproject.component.auth.routes.authRegister
import fr.dcproject.component.auth.jwt.jwtInstallation
import fr.dcproject.component.auth.routes.installAuthRoutes
import fr.dcproject.component.auth.user
import fr.dcproject.component.citizen.routes.changeMyPassword
import fr.dcproject.component.citizen.routes.findCitizen
import fr.dcproject.component.citizen.routes.getCurrentCitizen
import fr.dcproject.component.citizen.routes.getOneCitizen
import fr.dcproject.component.comment.article.routes.createCommentArticle
import fr.dcproject.component.comment.article.routes.getArticleComments
import fr.dcproject.component.comment.article.routes.getCitizenArticleComments
import fr.dcproject.component.comment.generic.routes.createCommentChildren
import fr.dcproject.component.comment.generic.routes.editComment
import fr.dcproject.component.comment.generic.routes.getChildrenComments
import fr.dcproject.component.comment.generic.routes.getOneComment
import fr.dcproject.component.citizen.routes.installCitizenRoutes
import fr.dcproject.component.comment.article.routes.installCommentArticleRoutes
import fr.dcproject.component.comment.generic.routes.installCommentRoutes
import fr.dcproject.component.follow.routes.article.FollowArticle.followArticle
import fr.dcproject.component.follow.routes.article.GetFollowArticle.getFollowArticle
import fr.dcproject.component.follow.routes.article.GetMyFollowsArticle.getMyFollowsArticle
@@ -86,14 +73,14 @@ import io.ktor.routing.Routing
import io.ktor.server.jetty.EngineMain
import io.ktor.util.KtorExperimentalAPI
import io.ktor.websocket.WebSockets
import java.time.Duration
import java.util.concurrent.CompletionException
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.eclipse.jetty.util.log.Slf4jLog
import org.koin.core.qualifier.named
import org.koin.ktor.ext.Koin
import org.koin.ktor.ext.get
import org.slf4j.event.Level
import java.time.Duration
import java.util.concurrent.CompletionException
fun main(args: Array<String>): Unit = EngineMain.main(args)
@@ -158,30 +145,13 @@ fun Application.module(env: Env = PROD) {
install(Routing.Feature) {
// trace { application.log.trace(it.buildText()) }
installArticleRoutes()
installAuthRoutes()
installCitizenRoutes()
installCommentArticleRoutes()
installCommentRoutes()
authenticate(optional = true) {
/* Article */
findArticles(get(), get())
getOneArticle(get(), get())
upsertArticle(get(), get(), get())
findArticleVersions(get(), get())
/* Citizen */
findCitizen(get(), get())
getOneCitizen(get())
getCurrentCitizen(get())
changeMyPassword(get(), get())
/* Comment */
editComment(get(), get())
getOneComment(get(), get())
createCommentChildren(get(), get())
getChildrenComments(get(), get())
/* Comment Article */
getArticleComments(get(), get())
createCommentArticle(get(), get())
getCitizenArticleComments(get(), get())
/* Auth */
authLogin(get())
authRegister(get())
authPasswordless(get())
/* Workgroup */
getWorkgroups(get(), get())
getWorkgroup(get(), get())

View File

@@ -14,6 +14,7 @@ import io.ktor.response.respond
import io.ktor.routing.Route
@KtorExperimentalLocationsAPI
object FindArticleVersions {
@Location("/articles/{article}/versions")
class ArticleVersionsRequest(
val article: ArticleForView,
@@ -27,11 +28,9 @@ class ArticleVersionsRequest(
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
}
@KtorExperimentalLocationsAPI
private fun ArticleRepository.findVersions(request: ArticleVersionsRequest) =
findVersionsByVersionId(request.page, request.limit, request.article.versionId)
@KtorExperimentalLocationsAPI
fun Route.findArticleVersions(repo: ArticleRepository, voter: ArticleVoter) {
get<ArticleVersionsRequest> {
repo.findVersions(it)
@@ -39,3 +38,4 @@ fun Route.findArticleVersions(repo: ArticleRepository, voter: ArticleVoter) {
.let { call.respond(it) }
}
}
}

View File

@@ -8,11 +8,14 @@ import fr.dcproject.voter.assert
import fr.postgresjson.connexion.Paginated
import fr.postgresjson.repository.RepositoryI
import io.ktor.application.call
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location
import io.ktor.locations.get
import io.ktor.response.respond
import io.ktor.routing.Route
@KtorExperimentalLocationsAPI
object FindArticles {
@Location("/articles")
class ArticlesRequest(
page: Int = 1,
@@ -45,3 +48,4 @@ fun Route.findArticles(repo: ArticleRepository, voter: ArticleVoter) {
.let { call.respond(it) }
}
}
}

View File

@@ -4,7 +4,7 @@ import fr.dcproject.component.article.ArticleForView
import fr.dcproject.component.article.ArticleRepository
import fr.dcproject.component.article.ArticleViewManager
import fr.dcproject.component.article.ArticleVoter
import fr.dcproject.component.article.routes.ArticleRequest.Output
import fr.dcproject.component.article.routes.GetOneArticle.ArticleRequest.Output
import fr.dcproject.component.auth.citizenOrNull
import fr.dcproject.dto.CreatedAt
import fr.dcproject.dto.Opinionable
@@ -19,18 +19,17 @@ import io.ktor.locations.Location
import io.ktor.locations.get
import io.ktor.response.respond
import io.ktor.routing.Route
import io.ktor.util.KtorExperimentalAPI
import kotlinx.coroutines.launch
import org.koin.core.KoinComponent
import org.koin.core.inject
import java.util.UUID
@KtorExperimentalLocationsAPI
object GetOneArticle {
@Location("/articles/{articleId}")
class ArticleRequest(val articleId: UUID) : KoinComponent {
val repo: ArticleRepository by inject()
@KtorExperimentalAPI
val article: ArticleForView = repo.findById(articleId) ?: throw NotFoundException("Article $articleId not found")
class Output(
@@ -54,8 +53,6 @@ class ArticleRequest(val articleId: UUID) : KoinComponent {
}
}
@KtorExperimentalAPI
@KtorExperimentalLocationsAPI
fun Route.getOneArticle(viewManager: ArticleViewManager, voter: ArticleVoter) {
get<ArticleRequest> {
voter.assert { canView(it.article, citizenOrNull) }
@@ -72,3 +69,4 @@ fun Route.getOneArticle(viewManager: ArticleViewManager, voter: ArticleVoter) {
}
}
}
}

View File

@@ -4,7 +4,7 @@ import fr.dcproject.component.article.ArticleForUpdate
import fr.dcproject.component.article.ArticleForView
import fr.dcproject.component.article.ArticleRepository
import fr.dcproject.component.article.ArticleVoter
import fr.dcproject.component.article.routes.PostArticleRequest.Input
import fr.dcproject.component.article.routes.UpsertArticle.UpsertArticleRequest.Input
import fr.dcproject.component.auth.citizen
import fr.dcproject.component.auth.citizenOrNull
import fr.dcproject.component.workgroup.WorkgroupRef
@@ -23,8 +23,9 @@ import io.ktor.routing.Route
import java.util.UUID
@KtorExperimentalLocationsAPI
object UpsertArticle {
@Location("/articles")
class PostArticleRequest {
class UpsertArticleRequest {
class Input(
val id: UUID?,
val title: String,
@@ -38,7 +39,6 @@ class PostArticleRequest {
)
}
@KtorExperimentalLocationsAPI
fun Route.upsertArticle(repo: ArticleRepository, workgroupRepository: WorkgroupRepository, voter: ArticleVoter) {
suspend fun ApplicationCall.convertRequestToEntity(): ArticleForUpdate = receive<Input>().run {
ArticleForUpdate(
@@ -55,15 +55,12 @@ fun Route.upsertArticle(repo: ArticleRepository, workgroupRepository: WorkgroupR
)
}
post<PostArticleRequest> {
post<UpsertArticleRequest> {
val article = call.convertRequestToEntity()
voter.assert { canUpsert(article, citizenOrNull) }
val newArticle: ArticleForView = repo.upsert(article) ?: error("Article not updated")
call.respond(newArticle)
raiseEvent(ArticleUpdate.event, ArticleUpdate(newArticle))
}
}
}

View File

@@ -0,0 +1,21 @@
package fr.dcproject.component.article.routes
import fr.dcproject.component.article.routes.FindArticleVersions.findArticleVersions
import fr.dcproject.component.article.routes.FindArticles.findArticles
import fr.dcproject.component.article.routes.GetOneArticle.getOneArticle
import fr.dcproject.component.article.routes.UpsertArticle.upsertArticle
import io.ktor.auth.authenticate
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.routing.Routing
import io.ktor.util.KtorExperimentalAPI
import org.koin.ktor.ext.get
@KtorExperimentalLocationsAPI
fun Routing.installArticleRoutes() {
authenticate(optional = true) {
findArticles(get(), get())
findArticleVersions(get(), get())
getOneArticle(get(), get())
upsertArticle(get(), get(), get())
}
}

View File

@@ -6,7 +6,7 @@ import com.sendgrid.helpers.mail.objects.Email
import fr.dcproject.component.citizen.CitizenRepository
import fr.dcproject.component.citizen.CitizenWithEmail
import fr.dcproject.component.citizen.CitizenWithUserI
import fr.dcproject.makeToken
import fr.dcproject.component.auth.jwt.makeToken
import fr.dcproject.messages.Mailer
import io.ktor.http.URLBuilder

View File

@@ -1,4 +1,4 @@
package fr.dcproject
package fr.dcproject.component.auth.jwt
import com.auth0.jwt.JWT
import fr.dcproject.component.auth.UserI

View File

@@ -1,8 +1,7 @@
package component.auth.jwt
package fr.dcproject.component.auth.jwt
import fr.dcproject.component.auth.User
import fr.dcproject.component.auth.UserRepository
import fr.dcproject.component.auth.jwt.JwtConfig
import io.ktor.application.ApplicationCall
import io.ktor.auth.Authentication
import io.ktor.auth.jwt.jwt

View File

@@ -2,7 +2,7 @@ package fr.dcproject.component.auth.routes
import com.fasterxml.jackson.databind.exc.MismatchedInputException
import fr.dcproject.component.auth.UserRepository
import fr.dcproject.makeToken
import fr.dcproject.component.auth.jwt.makeToken
import io.ktor.application.call
import io.ktor.auth.UserPasswordCredential
import io.ktor.http.HttpStatusCode
@@ -13,14 +13,12 @@ import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.response.respondText
import io.ktor.routing.Route
import io.ktor.util.KtorExperimentalAPI
@KtorExperimentalLocationsAPI
object Login {
@Location("/login")
class LoginRequest
@KtorExperimentalLocationsAPI
@KtorExperimentalAPI
fun Route.authLogin(userRepo: UserRepository) {
post<LoginRequest> {
try {
@@ -33,3 +31,4 @@ fun Route.authLogin(userRepo: UserRepository) {
}
}
}
}

View File

@@ -3,11 +3,11 @@ package fr.dcproject.component.auth.routes
import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException
import fr.dcproject.component.auth.User
import fr.dcproject.component.auth.UserI
import fr.dcproject.component.auth.routes.RegisterRequest.Input
import fr.dcproject.component.auth.routes.Register.RegisterRequest.Input
import fr.dcproject.component.citizen.Citizen
import fr.dcproject.component.citizen.CitizenI
import fr.dcproject.component.citizen.CitizenRepository
import fr.dcproject.makeToken
import fr.dcproject.component.auth.jwt.makeToken
import io.ktor.application.call
import io.ktor.features.BadRequestException
import io.ktor.http.HttpStatusCode
@@ -18,10 +18,10 @@ import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.response.respondText
import io.ktor.routing.Route
import io.ktor.util.KtorExperimentalAPI
import org.joda.time.DateTime
@KtorExperimentalLocationsAPI
object Register {
@Location("/register")
class RegisterRequest {
data class Input(
@@ -44,8 +44,6 @@ class RegisterRequest {
}
}
@KtorExperimentalLocationsAPI
@KtorExperimentalAPI
fun Route.authRegister(citizenRepo: CitizenRepository) {
fun Input.toCitizen(): Citizen = Citizen(
name = CitizenI.Name(name.firstName, name.lastName, name.civility),
@@ -70,3 +68,4 @@ fun Route.authRegister(citizenRepo: CitizenRepository) {
}
}
}
}

View File

@@ -1,7 +1,7 @@
package fr.dcproject.component.auth.routes
import fr.dcproject.component.auth.PasswordlessAuth
import fr.dcproject.component.auth.routes.PasswordlessRequest.Input
import fr.dcproject.component.auth.routes.Sso.PasswordlessRequest.Input
import io.ktor.application.call
import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI
@@ -10,9 +10,9 @@ import io.ktor.locations.post
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.routing.Route
import io.ktor.util.KtorExperimentalAPI
@KtorExperimentalLocationsAPI
object Sso {
@Location("/auth/passwordless")
class PasswordlessRequest {
data class Input(val email: String, val url: String)
@@ -21,8 +21,6 @@ class PasswordlessRequest {
/**
* Send an email to the citizen with a link to automatically connect
*/
@KtorExperimentalLocationsAPI
@KtorExperimentalAPI
fun Route.authPasswordless(passwordlessAuth: PasswordlessAuth) {
post<PasswordlessRequest> {
call.receive<Input>().run {
@@ -35,3 +33,4 @@ fun Route.authPasswordless(passwordlessAuth: PasswordlessAuth) {
}
}
}
}

View File

@@ -0,0 +1,19 @@
package fr.dcproject.component.auth.routes
import fr.dcproject.component.auth.routes.Login.authLogin
import fr.dcproject.component.auth.routes.Register.authRegister
import fr.dcproject.component.auth.routes.Sso.authPasswordless
import io.ktor.auth.authenticate
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.routing.Routing
import io.ktor.util.KtorExperimentalAPI
import org.koin.ktor.ext.get
@KtorExperimentalLocationsAPI
fun Routing.installAuthRoutes() {
authenticate(optional = true) {
authLogin(get())
authRegister(get())
authPasswordless(get())
}
}

View File

@@ -18,13 +18,12 @@ import io.ktor.response.respond
import io.ktor.routing.Route
@KtorExperimentalLocationsAPI
object ChangeMyPassword {
@Location("/citizens/{citizen}/password/change")
class ChangePasswordCitizenRequest(val citizen: Citizen) {
data class Input(val oldPassword: String, val newPassword: String)
}
@KtorExperimentalLocationsAPI
fun Route.changeMyPassword(voter: CitizenVoter, userRepository: UserRepository) {
put<ChangePasswordCitizenRequest> {
voter.assert { canChangePassword(it.citizen, citizenOrNull) }
@@ -45,3 +44,4 @@ fun Route.changeMyPassword(voter: CitizenVoter, userRepository: UserRepository)
}
}
}
}

View File

@@ -13,6 +13,7 @@ import io.ktor.response.respond
import io.ktor.routing.Route
@KtorExperimentalLocationsAPI
object FindCitizens {
@Location("/citizens")
class CitizensRequest(
page: Int = 1,
@@ -25,7 +26,6 @@ class CitizensRequest(
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
}
@KtorExperimentalLocationsAPI
fun Route.findCitizen(voter: CitizenVoter, repo: CitizenRepository) {
get<CitizensRequest> {
val citizens = repo.find(it.page, it.limit, it.sort, it.direction, it.search)
@@ -33,3 +33,4 @@ fun Route.findCitizen(voter: CitizenVoter, repo: CitizenRepository) {
call.respond(citizens)
}
}
}

View File

@@ -13,10 +13,10 @@ import io.ktor.response.respond
import io.ktor.routing.Route
@KtorExperimentalLocationsAPI
object GetCurrentCitizen {
@Location("/citizens/current")
class CurrentCitizenRequest
@KtorExperimentalLocationsAPI
fun Route.getCurrentCitizen(voter: CitizenVoter) {
get<CurrentCitizenRequest> {
val currentUser = citizenOrNull
@@ -28,3 +28,4 @@ fun Route.getCurrentCitizen(voter: CitizenVoter) {
}
}
}
}

View File

@@ -12,10 +12,10 @@ import io.ktor.response.respond
import io.ktor.routing.Route
@KtorExperimentalLocationsAPI
object GetOneCitizen {
@Location("/citizens/{citizen}")
class CitizenRequest(val citizen: Citizen)
@KtorExperimentalLocationsAPI
fun Route.getOneCitizen(voter: CitizenVoter) {
get<CitizenRequest> {
voter.assert { canView(it.citizen, citizenOrNull) }
@@ -23,3 +23,4 @@ fun Route.getOneCitizen(voter: CitizenVoter) {
call.respond(it.citizen)
}
}
}

View File

@@ -0,0 +1,24 @@
package fr.dcproject.component.citizen.routes
import fr.dcproject.component.auth.routes.Login.authLogin
import fr.dcproject.component.auth.routes.Register.authRegister
import fr.dcproject.component.auth.routes.Sso.authPasswordless
import fr.dcproject.component.citizen.routes.ChangeMyPassword.changeMyPassword
import fr.dcproject.component.citizen.routes.FindCitizens.findCitizen
import fr.dcproject.component.citizen.routes.GetCurrentCitizen.getCurrentCitizen
import fr.dcproject.component.citizen.routes.GetOneCitizen.getOneCitizen
import io.ktor.auth.authenticate
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.routing.Routing
import io.ktor.util.KtorExperimentalAPI
import org.koin.ktor.ext.get
@KtorExperimentalLocationsAPI
fun Routing.installCitizenRoutes() {
authenticate(optional = true) {
findCitizen(get(), get())
getOneCitizen(get())
getCurrentCitizen(get())
changeMyPassword(get(), get())
}
}

View File

@@ -18,6 +18,7 @@ import io.ktor.response.respond
import io.ktor.routing.Route
@KtorExperimentalLocationsAPI
object CreateCommentArticle {
@Location("/articles/{article}/comments")
class PostArticleCommentRequest(
val article: ArticleForView
@@ -35,7 +36,6 @@ class PostArticleCommentRequest(
}
}
@KtorExperimentalLocationsAPI
fun Route.createCommentArticle(repo: CommentArticleRepository, voter: CommentVoter) {
post<PostArticleCommentRequest> {
it.getComment(call).let { comment ->
@@ -45,3 +45,4 @@ fun Route.createCommentArticle(repo: CommentArticleRepository, voter: CommentVot
}
}
}
}

View File

@@ -14,6 +14,7 @@ import io.ktor.response.respond
import io.ktor.routing.Route
@KtorExperimentalLocationsAPI
object GetArticleComments {
@Location("/articles/{article}/comments")
class ArticleCommentsRequest(
val article: ArticleRef,
@@ -27,7 +28,6 @@ class ArticleCommentsRequest(
val sort: CommentArticleRepository.Sort = CommentArticleRepository.Sort.fromString(sort) ?: CommentArticleRepository.Sort.CREATED_AT
}
@KtorExperimentalLocationsAPI
fun Route.getArticleComments(repo: CommentArticleRepository, voter: CommentVoter) {
get<ArticleCommentsRequest> {
val comment = repo.findByTarget(it.article, it.page, it.limit, it.sort)
@@ -37,3 +37,4 @@ fun Route.getArticleComments(repo: CommentArticleRepository, voter: CommentVoter
call.respond(HttpStatusCode.OK, comment)
}
}
}

View File

@@ -13,10 +13,10 @@ import io.ktor.response.respond
import io.ktor.routing.Route
@KtorExperimentalLocationsAPI
object GetCitizenArticleComments {
@Location("/citizens/{citizen}/comments/articles")
class CitizenCommentArticleRequest(val citizen: Citizen)
@KtorExperimentalLocationsAPI
fun Route.getCitizenArticleComments(repo: CommentArticleRepository, voter: CommentVoter) {
get<CitizenCommentArticleRequest> {
repo.findByCitizen(it.citizen).let { comments ->
@@ -25,3 +25,4 @@ fun Route.getCitizenArticleComments(repo: CommentArticleRepository, voter: Comme
}
}
}
}

View File

@@ -0,0 +1,18 @@
package fr.dcproject.component.comment.article.routes
import fr.dcproject.component.comment.article.routes.CreateCommentArticle.createCommentArticle
import fr.dcproject.component.comment.article.routes.GetArticleComments.getArticleComments
import fr.dcproject.component.comment.article.routes.GetCitizenArticleComments.getCitizenArticleComments
import io.ktor.auth.authenticate
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.routing.Routing
import org.koin.ktor.ext.get
@KtorExperimentalLocationsAPI
fun Routing.installCommentArticleRoutes() {
authenticate(optional = true) {
getArticleComments(get(), get())
createCommentArticle(get(), get())
getCitizenArticleComments(get(), get())
}
}

View File

@@ -19,13 +19,12 @@ import io.ktor.routing.Route
import io.ktor.util.KtorExperimentalAPI
@KtorExperimentalLocationsAPI
object CreateCommentChildren {
@Location("/comments/{comment}/children")
class CreateCommentChildrenRequest(val comment: CommentRef) {
class Input(val content: String)
}
@KtorExperimentalAPI
@KtorExperimentalLocationsAPI
fun Route.createCommentChildren(repo: CommentRepository, voter: CommentVoter) {
post<CreateCommentChildrenRequest> {
val parent = repo.findById(it.comment.id) ?: throw NotFoundException("Comment not found")
@@ -41,3 +40,4 @@ fun Route.createCommentChildren(repo: CommentRepository, voter: CommentVoter) {
call.respond(HttpStatusCode.Created, newComment)
}
}
}

View File

@@ -14,14 +14,12 @@ import io.ktor.locations.put
import io.ktor.request.receiveText
import io.ktor.response.respond
import io.ktor.routing.Route
import io.ktor.util.KtorExperimentalAPI
@KtorExperimentalLocationsAPI
object EditComment {
@Location("/comments/{comment}")
class EditCommentRequest(val comment: CommentRef)
@KtorExperimentalAPI
@KtorExperimentalLocationsAPI
fun Route.editComment(repo: CommentRepository, voter: CommentVoter) {
put<EditCommentRequest> {
val comment = repo.findById(it.comment.id) ?: throw NotFoundException("Comment not found")
@@ -33,3 +31,4 @@ fun Route.editComment(repo: CommentRepository, voter: CommentVoter) {
call.respond(HttpStatusCode.OK, comment)
}
}
}

View File

@@ -15,6 +15,7 @@ import io.ktor.util.KtorExperimentalAPI
import java.util.UUID
@KtorExperimentalLocationsAPI
object GetCommentChildren {
@Location("/comments/{comment}/children")
class CommentChildrenRequest(
val comment: UUID,
@@ -26,8 +27,6 @@ class CommentChildrenRequest(
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
}
@KtorExperimentalAPI
@KtorExperimentalLocationsAPI
fun Route.getChildrenComments(repo: CommentRepository, voter: CommentVoter) {
get<CommentChildrenRequest> {
val comments =
@@ -42,3 +41,4 @@ fun Route.getChildrenComments(repo: CommentRepository, voter: CommentVoter) {
call.respond(HttpStatusCode.OK, comments)
}
}
}

View File

@@ -16,11 +16,10 @@ import io.ktor.routing.Route
import io.ktor.util.KtorExperimentalAPI
@KtorExperimentalLocationsAPI
object GetOneComment {
@Location("/comments/{comment}")
class CommentRequest(val comment: CommentRef)
@KtorExperimentalAPI
@KtorExperimentalLocationsAPI
fun Route.getOneComment(repo: CommentRepository, voter: CommentVoter) {
get<CommentRequest> {
val comment = repo.findById(it.comment.id) ?: throw NotFoundException("Comment ${it.comment.id} not found")
@@ -29,3 +28,4 @@ fun Route.getOneComment(repo: CommentRepository, voter: CommentVoter) {
call.respond(HttpStatusCode.OK, comment)
}
}
}

View File

@@ -0,0 +1,20 @@
package fr.dcproject.component.comment.generic.routes
import fr.dcproject.component.comment.generic.routes.CreateCommentChildren.createCommentChildren
import fr.dcproject.component.comment.generic.routes.EditComment.editComment
import fr.dcproject.component.comment.generic.routes.GetCommentChildren.getChildrenComments
import fr.dcproject.component.comment.generic.routes.GetOneComment.getOneComment
import io.ktor.auth.authenticate
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.routing.Routing
import org.koin.ktor.ext.get
@KtorExperimentalLocationsAPI
fun Routing.installCommentRoutes() {
authenticate(optional = true) {
editComment(get(), get())
getOneComment(get(), get())
createCommentChildren(get(), get())
getChildrenComments(get(), get())
}
}