From f8b4a1cb01f85885a0915c940efc40f00906ffc4 Mon Sep 17 00:00:00 2001 From: Lucas Evard Date: Wed, 11 Oct 2023 12:51:53 +0200 Subject: [PATCH] :sparkles: add User routes and serialization --- Sources/pom.xml | 69 +++++++++++++++++- Sources/src/main/kotlin/allin/Application.kt | 21 ++++-- .../main/kotlin/allin/entities/UserEntity.kt | 11 +++ Sources/src/main/kotlin/allin/model/User.kt | 6 ++ .../src/main/kotlin/allin/plugins/Routing.kt | 62 +++++++++++++++- .../main/kotlin/allin/routing/BasicRouting.kt | 13 ++++ .../main/kotlin/allin/routing/UserRouter.kt | 57 +++++++++++++++ .../classes/META-INF/allin-api.kotlin_module | Bin 76 -> 95 bytes .../classes/allin/ApplicationKt$main$1.class | Bin 1569 -> 1543 bytes .../target/classes/allin/ApplicationKt.class | Bin 1738 -> 2229 bytes .../RoutingKt$configureRouting$1$1.class | Bin 4373 -> 0 bytes .../RoutingKt$configureRouting$1.class | Bin 1941 -> 0 bytes .../classes/allin/plugins/RoutingKt.class | Bin 1140 -> 0 bytes 13 files changed, 231 insertions(+), 8 deletions(-) create mode 100644 Sources/src/main/kotlin/allin/entities/UserEntity.kt create mode 100644 Sources/src/main/kotlin/allin/model/User.kt create mode 100644 Sources/src/main/kotlin/allin/routing/BasicRouting.kt create mode 100644 Sources/src/main/kotlin/allin/routing/UserRouter.kt delete mode 100644 Sources/target/classes/allin/plugins/RoutingKt$configureRouting$1$1.class delete mode 100644 Sources/target/classes/allin/plugins/RoutingKt$configureRouting$1.class delete mode 100644 Sources/target/classes/allin/plugins/RoutingKt.class diff --git a/Sources/pom.xml b/Sources/pom.xml index bed0ed5..56bd3a7 100644 --- a/Sources/pom.xml +++ b/Sources/pom.xml @@ -8,6 +8,8 @@ allin-api allin-api + 1.8.10 + 1.5.0 2.3.4 official 1.9.10 @@ -51,6 +53,36 @@ ${ktor_version} test + + io.ktor + ktor-server-core + ${ktor_version} + + + com.h2database + h2 + 2.2.224 + + + io.ktor + ktor-server-content-negotiation-jvm + ${ktor_version} + + + io.ktor + ktor-server-html-builder-jvm + ${ktor_version} + + + io.ktor + ktor-serialization-kotlinx-json-jvm + ${ktor_version} + + + io.ktor + ktor-client-content-negotiation-jvm + ${ktor_version} + org.jetbrains.kotlin kotlin-test-junit @@ -63,6 +95,16 @@ 1.6.4 test + + org.jetbrains.kotlinx + kotlinx-serialization-core-jvm + 1.5.1 + + + io.ktor + ktor-server-content-negotiation-jvm + ${ktor_version} + ${project.basedir}/src/main/kotlin @@ -72,7 +114,6 @@ ${project.basedir}/src/main/resources - kotlin-maven-plugin @@ -138,6 +179,32 @@ + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + + + kotlinx-serialization + + + + + org.jetbrains.kotlin + kotlin-maven-serialization + ${kotlin.version} + + + \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/Application.kt b/Sources/src/main/kotlin/allin/Application.kt index 7796f9b..15afe0f 100644 --- a/Sources/src/main/kotlin/allin/Application.kt +++ b/Sources/src/main/kotlin/allin/Application.kt @@ -1,15 +1,26 @@ package allin -import allin.plugins.* +import allin.routing.BasicRouting +import allin.routing.UserRouter +import io.ktor.http.* +import io.ktor.serialization.kotlinx.json.* import io.ktor.server.application.* import io.ktor.server.engine.* import io.ktor.server.netty.* +import io.ktor.server.plugins.contentnegotiation.* +import io.ktor.server.response.* +import io.ktor.server.routing.* fun main() { - embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = Application::module) - .start(wait = true) + embeddedServer(Netty,port=8080,host="0.0.0.0"){ + extracted() + }.start(wait = true) } -fun Application.module() { - configureRouting() +private fun Application.extracted() { + install(ContentNegotiation) { + json() + } + BasicRouting() + UserRouter() } diff --git a/Sources/src/main/kotlin/allin/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/entities/UserEntity.kt new file mode 100644 index 0000000..d8f0996 --- /dev/null +++ b/Sources/src/main/kotlin/allin/entities/UserEntity.kt @@ -0,0 +1,11 @@ +package allin.entities + +import org.ktorm.schema.Table +import org.ktorm.schema.int +import org.ktorm.schema.varchar + +object UserEntity : Table("user") { + val id = int("id").primaryKey() + val username = varchar("username") + val password = varchar("password") +} \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/model/User.kt b/Sources/src/main/kotlin/allin/model/User.kt new file mode 100644 index 0000000..4921f91 --- /dev/null +++ b/Sources/src/main/kotlin/allin/model/User.kt @@ -0,0 +1,6 @@ +package allin.model + +import kotlinx.serialization.Serializable + +@Serializable +data class User(val username: String, val email: String, val password: String, var nbCoins: Int) diff --git a/Sources/src/main/kotlin/allin/plugins/Routing.kt b/Sources/src/main/kotlin/allin/plugins/Routing.kt index bc358d8..73bdd9e 100644 --- a/Sources/src/main/kotlin/allin/plugins/Routing.kt +++ b/Sources/src/main/kotlin/allin/plugins/Routing.kt @@ -1,13 +1,71 @@ -package allin.plugins +/*package allin.plugins +import allin.model.User +import io.ktor.http.* import io.ktor.server.application.* +import io.ktor.server.html.* +import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* +import kotlinx.html.body +import kotlinx.html.h1 +val users = mutableListOf() fun Application.configureRouting() { routing { get("/") { - call.respondText("Hello World!") + call.respondHtml(HttpStatusCode.OK) { + body { + h1 { + +"Bienvenue dans l'API de l'application ALLin!" + } + } + } + } + + route("/users") { + get { + call.respondText(users.joinToString("\n"), ContentType.Text.Plain) + } + post { + val newUser = call.receive() + users.add(newUser) + call.respond(HttpStatusCode.Created, newUser) + } + } + + route("/users/{username}") { + get { + val username = call.parameters["username"] + val user = users.find { it.username == username } + if (user != null) { + call.respond(user) + } else { + call.respond(HttpStatusCode.NotFound) + } + } + put { + val username = call.parameters["username"] + val userIndex = users.indexOfFirst { it.username == username } + if (userIndex != -1) { + val updatedUser = call.receive() + users[userIndex] = updatedUser + call.respond(updatedUser) + } else { + call.respond(HttpStatusCode.NotFound) + } + } + delete { + val username = call.parameters["username"] + val user = users.find { it.username == username } + if (user != null) { + users.remove(user) + call.respond(HttpStatusCode.NoContent) + } else { + call.respond(HttpStatusCode.NotFound) + } + } } } } +*/ \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/routing/BasicRouting.kt b/Sources/src/main/kotlin/allin/routing/BasicRouting.kt new file mode 100644 index 0000000..0d78278 --- /dev/null +++ b/Sources/src/main/kotlin/allin/routing/BasicRouting.kt @@ -0,0 +1,13 @@ +package allin.routing + +import io.ktor.server.application.* +import io.ktor.server.response.* +import io.ktor.server.routing.* + +fun Application.BasicRouting(){ + routing { + get("/") { + call.respond("Bienvenue sur l'API de AlLin!") + } + } +} \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/routing/UserRouter.kt b/Sources/src/main/kotlin/allin/routing/UserRouter.kt new file mode 100644 index 0000000..6df81fd --- /dev/null +++ b/Sources/src/main/kotlin/allin/routing/UserRouter.kt @@ -0,0 +1,57 @@ +package allin.routing + +import allin.model.User +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.request.* +import io.ktor.server.response.* +import io.ktor.server.routing.* + +val users = mutableListOf(User("user1", "user1@example.com", "mdp",1000)) +fun Application.UserRouter() { + routing { + route("/users") { + get { + call.respond(users) + } + post { + val newUser = call.receive() + users.add(newUser) + call.respond(HttpStatusCode.Created, newUser) + } + } + + route("/users/{username}") { + get { + val username = call.parameters["username"] + val user = users.find { it.username == username } + if (user != null) { + call.respond(user) + } else { + call.respond(HttpStatusCode.NotFound) + } + } + put { + val username = call.parameters["username"] + val userIndex = users.indexOfFirst { it.username == username } + if (userIndex != -1) { + val updatedUser = call.receive() + users[userIndex] = updatedUser + call.respond(updatedUser) + } else { + call.respond(HttpStatusCode.NotFound) + } + } + delete { + val username = call.parameters["username"] + val user = users.find { it.username == username } + if (user != null) { + users.remove(user) + call.respond(HttpStatusCode.NoContent) + } else { + call.respond(HttpStatusCode.NotFound) + } + } + } + } +} diff --git a/Sources/target/classes/META-INF/allin-api.kotlin_module b/Sources/target/classes/META-INF/allin-api.kotlin_module index 12d8f45b2b4a1183dcb64dbd0aa63e53e83e8a0e..f63b2d75921d2022254860a4d20694db21534b7e 100644 GIT binary patch delta 69 zcmeZ?=V4%AU@HTPi{+3J6tctF#~rQl!*^GTN{KO-xrqXA&!Pnsh3{if)YS zW`2SG0!1T46Kq`i7g(A2AKV%5YtfyHx%a&L&N=tKn|UK%i_rJqpHBeHqQnq)zq0s* zAB@2%ZP%MSRXg*1x0b2eO{-xWJDHME+cJ$@sr_T5{c>SA{(nyUbUy5v)RRvHRA?H! z2)ZBHt5|=c`K;)a>=@f%DAN}v>Pz6Z3z?xzE_nfOURsNNOW34>$Ef; z;Tn%|f{{)u&a*7VvwTha_SVN$sWNA1s71rB+xxZp3ulQ*Q%}vP+5*e&FXiL_S!(K~ zDy<(watdnWp-)ACDn&vGVvrENl;;TIJt2k_ilSFVsH^FddmyG%6e)Ac!F2TeF^1B| z7?CoLRf=*~KB8*q!^!~_2725xA5tNTQS!b|cYfLd@enDH{TN|szf1yYFH-3a#y=r( zh}1he_xyd`vBKREd)DHgwLluz>0ZT+-t%Pt!LAwg{Q~~<2$>ILL3SncJn5g#Q4~1bj#U delta 776 zcma)(%TE(g7{$+>8QN**R?48IR7ItVeJC?1DpHk}0y3tu5Ft@l6CBCF^cKrN+>w|V z*Jk!6{0BY~AsUGrW8xoW{BDbng$oyRzjMz$-|s%=CEw+#?>{~s02s#|hFsLka&{by z;dx`d6$ZYr*0!6LFG8;^+`yXK5-XwK68F3(UfUBZp3~e2Ud=x&75_i|c_QjpGT9_U ztl4_J6?i&0!&p}r8qsTISx+GTl`i@vg%%n6)K;y8vlI5J5XIL*-AJ$kAv)y{GplfHrx z2IKH{OTrK1C@|>G!s7kfLVcDY_3NSJVuhoGasowMh~ny~F(&6n6GXWjRn_5qLZzn$ z16!9uWl)~^QrQez)Aa?%t>~M2u#>i_rH6v_FEA(>6w>I^kszl=s*D&ZAXU;#!%UgI z+8)feWH3zA$h(W^@3i*G%MemFPEl2;8f9~EAE(OuI3wE>)M=E=7cB;#dM=@5K@DGDeunY@Y!Q=ycbSzOwsy`bOr8%+O$ z-!U;+{9yRZKhU3GqW%Npx!YhEO-$Q!+vlF=JkL43hb8n%{8D|5yk*RM}dpKH<^m`Kr;BDbj6q4UBQs`WEEQn;)k zi7O13f}hHTjoL;SgA8%ANJfo`QmJTLRqa`kIBqR56h@j@x&LI5Mg-R)7{V~aAZhfC z)-kMIPQ&0_tHv_q&Dg1j<8QDd1-FhzQXWivYGPh&ynMToc3da1_4z~me-oz~p zH!#Z3RdeT2=Qd?bn!atxG0=z9&oJmGF&%f%tKl}r8Df7@SLn}F2k1%SJqC@C-a4dX zQt~D+#n74%uWY|DD2Cv>k_-mb9ySv!s`36d)3UgKB11<)vK2gLh$K92ahuLS;1HuZ zc&Emh5$vnoEqa?0Q_?J@q?=}x;H$b8tcNB}tLQ`sr@*igybleRH|ZdrK@-JRbfF!W z5JgN1$P7Z4X^+u*F?E3c3a%c&_<)fEoU34LHC4e~dhYL2f`UzoQK%FZFn} zn1txHB6xslpe;fc9##d)Ko4z81+{{#EW}O_R6N2g5jv4Oc4Sb7%ny*t@?bvJ SkM^jo#Dd09FrASC9E5{gj(#aUv<81p8 zv*RziK#EwfVb?$42iPIO4v$4YSN4n{+l zOBE*47p^B&LUJCYHtGx)gS{}=Khf{_i9ZY}kYRSNJ@7}qD|{Kb-TojHfoh$i-sD-L zR{d=mw{Y7*1M>`*e394tD6%N;a5v5r1#K%EE<+`V3 z$Kx{SUq)SjE6lJ5`bS|}FId-DQFpCrHm_rAs^nCRD@KzwjHanSS?_Aq-ApPz3_UsG zDesH$-yrM%A4&hVHcBQgqW}vGTYAl2JlLkkJ_nQbBCf*0b(AQgiW&@T5&MXc5tbU0 zb7L$t##lTg*FY|G2rZI3IFB~@<>OHLy(RKqk=cx>n?R*VRqy9jiJT$Jb54wrJj}DP zQ|bvSxlEji4($%zO%kF4bO{W2*dbgdzC|fldN4ga_OR+<4Np9*SKRHe@36%?lZap!eFmH^rfsd=YGz&zsuR@6Mz5LpZ@}2 z5}yf-7?x$)dfBQJP21DgoQiMS#RWf^ckCUrSaD@-D49;CqY(UC+;@DnC-1nyYU$~F z2PNIKed*eUrROSMS=xm~qqJQxrt7QKlAVg3_f3a#=4-9@W)@9H-}fC?r(jDjn`Ozf zrM_Bg%sD*v(4VOvvtgV5bYqVv-2>_BM!9U6c|#qo&oC=R`5!MX;*^n zGovR2ar2&WVCa@%7xk6xJ(>4;Ag$JV%JWSSMMU7u+K%U#A&Pc^_8F7feIU?3SVwWp z#>Zh!4{ZvpU$lzKyo`6LnL0K(n7vqf3?1mw(1w^m#NRbNfw7kpCeXzgE0ry&+$NB? zNT|Ri(>`$aWi7r0-W_c9&QR-+f_8zwZprORaY_0{!SD_GSL_IAwZI?S_c>sNd1Ev- zOn%f>5V9!o%h&JFSnUptoqvaD;6=wR>U+}Pb`5ps4BK}6Ao@Igxnfzywk3(7|GZ_6 zuU2x^P^)IVh%V1H^PZk~iLQZX>svS-zFIC2)1{49msP zkEDjL;2nWB;*u5>&c-l+!A^uQByhPVeocB6%U42%1-kuR*LkpF&l{#i0ugxSEJtm| zFp4n^BhUrHi^*|;zEl6I;eDmV4crt+)layXIHH&m zh~1W!%l}UQ?I5*K?!C0LLJ!QLZ2wbTyF07OE zk_EYA(5wRg7FUyKuqF5Br^CZKB?<59j;z~&lB(~*_ z%cml@X3QZ*ZUN1NyeMNK*LMtK4!eOm#VuIq@;PkKuem*9d(F$vjn0^ zg;9CFr>R=if>C^%FGUryz-}`z&KG&YcJ)p}S1*W(`Xe}fhLZ&T_=2MTXHWGRsFkBS zHL}NdW9Y*b)w(YbDyLO3p$gK`-~(KDp0qs8N+t$hb5=tk&`HBq!FDLvmZk=WHS6xFP=a|@gT@tPLp3XqpW9^ zOfh1(hlf16Zl9BxlT&f?GI)V~Ddo;dJnOp_d@Z%8rTfz(>B*_I_Wt$$iK+DU zCg4C-E%o1_Ruabh)4{8OAw1d4wBFBg^3%kJg^EizVinxJpKYpcl%bJV(qUyER3JAyoSiXkw7~&jp8l` zf^zZ}s|bG1{+k>LQ{53_OjDPetk>AThc4V_t#qBFu|}v>4(lw(xMG8?FxN+^!yrwT z#B|LPs&$8k6!-;qwzGbV^)LBFNnL~jnuesuP0BPIJf@9x{0oHcjy}crrXumk@aLF} zN2t*geE%^gs}@fMu8B7+9*02`%64&VBOCZ5jy#VK*SzqZ77SOyH4IfG0l1!7;wf-k z;aQ>(6#>1eVLD;t2p^8p>`$>ep2G|Fo4q@n7h47S}ZgtIWS*vn!cRu(1LSvV+jvxgtR-9noO&x7w_-9yF0 SK@dmX^zo1Q{Ww_nlm7ru#^mk* diff --git a/Sources/target/classes/allin/plugins/RoutingKt$configureRouting$1.class b/Sources/target/classes/allin/plugins/RoutingKt$configureRouting$1.class deleted file mode 100644 index 4462df98d80eb59b18e5defee079cda06c077088..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1941 zcma)6Yf~Fl7=F%@X2Y@-h_+mcZI#$^sa+`5szGduU{}(#0;M9K4x7_($mVQjFB$#D zZ}As+nURj2aWehrk8*rZve4AhSY~qe@m!7-w{E?}Hts!xf8iAe_L;LtEs zL$hze#2E_pxAjtSwx0t;(Z+SmSh$8+hO7Oy>S{1tJELl|J!MM^N&589-NeT>hB0En zfWt79YOmjxiA9E-TiMz!RaV!?cPANk9-fUQ+#bX&e8ONfX=nZ{_S~{ZZGaw@eoKRz zN*&p#UG`P7AUF`XQ6#$TkRvu z7%?nk+@NrzeKct-usLJFxNp7qIcwzfsp>6CZJDb;{nQAOh@Lrtj=jN~Cdv#W|LtrH z^RHQgH=DlnI<9m|FXN6wD|pCYrET$Moh+4E4XV@%^5wwe{tgc%-}l9~9vFtpQi)2^ z*cV|sQ`k(%^9|vumW(8AI(@RGmtBFuc9jz0s?VcHP=6X;Q=T70-Tfav~+z>B9G*Vu7l2jufI^jtN~Zk~~8{Dk05mQdFQFBqFkNnPb?$ zQpB)Dqurgw`OcY9?JU}w&gUp>5p3XSANf=cnn8b+CY;=P-7UQT!cW>brt++MzL@k^$q?l=R;?p3s=V z13bd_6d4%6Zs+?QexUCiB3Pl*U+rPQ#a$OA7x%F0;%ltASjRVeU=i-a-9skAw-GiX I%tsjh7xN+e;{X5v diff --git a/Sources/target/classes/allin/plugins/RoutingKt.class b/Sources/target/classes/allin/plugins/RoutingKt.class deleted file mode 100644 index 5809412e5a1408f5ba072379eef0d58219e2ff5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1140 zcma)6OHUI~7(I6ieT+p)m8S{_RiHek;A>H1Bt(*lwHhF}V0Amal-o}4G;{AXF8Mib zbwykl;?f^w{06GjstJpJkJJ0TPv-lNFJA#X##4q#?)y?X9Y1PFrJcPXGEy~On-myB zuF1RH@wsX^Z);8A5t<;>3)Hb}M4{-tW>{UW$iQitAat|{yCQUWr{hbH8yP5P`^qk_ z95O6cg0SHgAQe0}qs@QD$(*#x(9SOcdhN{k1HHYq!HN_N${e!tgpboG4+n zy9pvLi$x|DU|_A-u;|YZGPX)&)i)Uy&QG)U`KfK?EZds0$egirB&-rES|#h-$0SkN zs&BD4N#^2a>%1cw>>jH(T83e0C#VaC(TY@}8ntU8Jm58-kbEWZxPQn)8T&o3uoo#K z+rm{{sU_jRX}EnwafYm`ln8fxuC>rqa6gDbPwdJ#?{qK4;bnrpIBdegP&_m>JdI%_ z$#=+mNt&iWzL?LPVYK)e!@c*P2(?fmX_HPOO-vi1JRquHL|_(kpuaWr#Hm_