Spring BootとCortlinを使用したブログWebの作成(4)
11949 ワード
Http APIの作成
セグメントプラグを使用してarticleリストとarticleのコントローラをクエリーする
ユーザー・リスト・クエリーとユーザー・ログイン・クエリーを生成するコントロール
src/main/kotlin/com/example/demo/HttpControllers.kt
package com.example.demo.blog
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.server.ResponseStatusException
@RestController
@RequestMapping("/api/articles")
class ArticleController (private val repositoriy: ArticleRepositoriy) {
@GetMapping("/")
fun findAll() = repositoriy.findAllByOrderByAddedAtDesc()
@GetMapping("/{slug}")
fun findOne(@PathVariable slug : String) =
repositoriy.findBySlug(slug)
?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "this article does not exist")
}
@RestController
@RequestMapping("/api/users")
class UserController(private val repositoriy: UserRepository){
@GetMapping("/")
fun findAll() = repositoriy.findAll();
@GetMapping("/{login}")
fun findOne(@PathVariable login: String) =
repositoriy.findByLogin(login)
?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "this user does not exist")
}
試験Http API
テストのために@WebMvcTestとMockkを使用します.MockkはMockitoと似ていますが、Cottinに適しています.
build.gradle.kts
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-mustache")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
developmentOnly("org.springframework.boot:spring-boot-devtools")
runtimeOnly("com.h2database:h2")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
testImplementation("org.springframework.boot:spring-boot-starter-test"){
exclude(module="junit")
exclude(module="mockito-core")
}
testImplementation("org.junit.jupiter:junit-jupiter-api")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
implementation("com.ninja-squad:springmockk:3.0.1")
}
既存のmockitoに加えてmockkを追加src/test/kotlin/com/example/demo/HttpControllersTests.kt
package com.example.demo
import com.example.demo.blog.Article
import com.example.demo.blog.ArticleRepositoriy
import com.example.demo.blog.User
import com.example.demo.blog.UserRepository
import com.ninjasquad.springmockk.MockkBean
import io.mockk.every
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.http.MediaType
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
@WebMvcTest
class HttpsControllersTests(@Autowired val mockMvc: MockMvc) {
@MockkBean
private lateinit var articleRepositoriy: ArticleRepositoriy
@MockkBean
private lateinit var userRepository: UserRepository
@Test
fun `List articles`() {
val user = User("login", "firstName", "lastName")
val article1 = Article("title1", "headline1", "content1", user)
val article2 = Article("title2", "headline2", "content2", user)
every { articleRepositoriy.findAllByOrderByAddedAtDesc() } returns
listOf(article1, article2)
mockMvc.perform(get("/api/articles/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("\$.[0].author.login").value(user.login))
.andExpect(jsonPath("\$.[0].slug").value(article1.slug))
.andExpect(jsonPath("\$.[1].author.login").value(article2.author.login))
.andExpect(jsonPath("\$.[1].slug").value(article2.slug))
}
@Test
fun `List users`() {
val user1 = User("login1", "firstName1", "lastName1")
val user2 = User("login2", "firstName2", "lastName2")
every { userRepository.findAll() } returns listOf(user1, user2)
mockMvc.perform(get("/api/users/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("\$.[0].login").value(user1.login))
.andExpect(jsonPath("\$.[1].login").value(user2.login))
}
}
List articlesのテストArticleRepositoryは各関数を通過します.findAllByOrderByAddDeAtDesc()の戻りリストを指定し、mockMvcを使用して
/api/articles/
APIが正常に動作しているかどうかを確認します.プロパティの設定
build.gradle.kts
plugins {
...
kotlin("kapt") version "1.4.32"
}
dependencies {
...
kapt("org.springframework.boot:spring-boot-configuration-processor")
}
コートリンは@ConstructureBindingと@ConfigurationPropertiesを使用してPropertyを管理することを推奨しますsrc/main/kotlin/com/example/demo/BlogProperties.kt
package com.example.demo
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConstructorBinding
@ConstructorBinding
@ConfigurationProperties("blog")
data class BlogProperties(var title: String, val banner: Banner) {
data class Banner(val title: String?=null, val content:String)
}
BlogApplicationレベルでPropertyを許可するsrc/main/kotlin/com/example/blog/BlogApplication.kt
package com.example.demo
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.runApplication
@SpringBootApplication
@EnableConfigurationProperties(BlogProperties::class)
class DemoApplication
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
application.propertiesでpropertyを設定します.src/main/resources/application.properties
blog.title=Blog
blog.banner.title=Warning
blog.banner.content=The Blog will be down tomorrow
コントローラでの使用src/main/kotlin/com/example/demo/HtmlController.kt
@Controller
class HtmlController (private val repository: ArticleRepositoriy,
private val properties: BlogProperties) {
@GetMapping("/")
fun blog(model: Model): String {
model["title"] = properties.title
model["banner"] = properties.banner
model["articles"] = repository.findAllByOrderByAddedAtDesc().map {
it.render()
}
return "blog"
}
// ...
最後にムスタッチに適用されます.src/main/kotlin/com/example/demo/HtmlController.kt
{{> header}}
<h1>{{title}}</h1>
<div class="articles">
{{#banner.title}}
<section>
<header class="banner">
<h2 class="banner-title">{{banner.title}}</h2>
</header>
<div class="banner-content">
{{banner.content}}
</div>
</section>
{{/banner.title}}
</div>
{{> footer}}
http://localhost:8080/活動場所を表すの結果を確認できますHttp APIを作成してテストし、Property設定も行いました.
これを使ってSpringBootとCortlinでブログサイトを作成して終了です.
ソースはここです。で確認できます.
Reference
https://spring.io/guides/tutorials/spring-boot-kotlin/
Reference
この問題について(Spring BootとCortlinを使用したブログWebの作成(4)), 我々は、より多くの情報をここで見つけました https://velog.io/@paulhana6006/스프링-부트와-코틀린-사용해서-블로그-웹-만들기-4テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol