RESUMO EM CONSTRUÇÃO
Curso teórico e prático para criação de projeto backend API REST, utilizando Spring Boot com Kotlin (ORM hibernate JPA DAO). Projeto com funcionalidades CRUD (Create, Read/List, Update, Delete). Banco de dados MySQL. Testes via Postman. Deploy em AWS (EC2).
Sistema web backend que suporta métodos HTTP REST (GET, POST, PUT, DELETE), transportando dados via header/body em request - response entre dispositivos comunicados em rede, via IPs em protocolo HTTP. Framework Spring Boot possui tecnologias necessárias para implementar padrão REST em projetos Java/Kotlin, usando padrões de código OOP (Programação Orientada a Objetos) e MVC (Model-View-Controller).
Instalação de pré-requisitos em ambiente Windows.
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.jetbrains.kotlin:kotlin-reflect")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
runtimeOnly("com.mysql:mysql-connector-j")
spring.application.name=bookstore
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/bookstore
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jackson.serialization.fail-on-empty-beans=false
server.error.include-message=always
server.error.include-binding-errors=always
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
server.port=8080
package ubsocial.com.bookstore.config
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.config.annotation.CorsRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
@Configuration
class WebConfig {
@Bean
fun corsConfigurer(): WebMvcConfigurer {
return object : WebMvcConfigurer {
override fun addCorsMappings(registry: CorsRegistry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8081")
.allowedMethods("GET","POST","PUT","DELETE","OPTIONS")
}
}
}
}
package ubsocial.com.bookstore.model.entity
import com.fasterxml.jackson.annotation.JsonFormat
import jakarta.persistence.*
import jakarta.validation.constraints.NotBlank
import jakarta.validation.constraints.NotNull
import jakarta.validation.constraints.Size
import java.time.LocalDate
@Entity
data class Book(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
val id: Long? = null,
@field:NotBlank
@field:Size(min = 1, max = 255, message = "Título precisa ter entre 1 e 255 caracteres")
@Column(length = 255)
val title: String = "",
@field:NotBlank
@field:Size(min = 1, max = 255, message = "Autor precisa ter entre 1 e 255 caracteres")
@Column(length = 255)
val author: String = "",
@field:NotNull
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
@Column(name = "published_date")
val published_date: LocalDate = LocalDate.now(),
@field:NotBlank
@field:Size(min = 13, max = 13, message = "ISBN precisa ter 13 caracteres")
@Column(unique = true)
val isbn: String = "",
val pages: Int = 0,
@field:Size(min = 1, max = 255, message = "Capa/Gênero precisa ter entre 1 e 255 caracteres")
@Column(length = 255)
val cover: String? = null,
@field:NotBlank
@field:Size(min = 1, max = 255, message = "Idioma precisa ter entre 1 e 255 caracteres")
@Column(length = 255)
val language: String = ""
)
package ubsocial.com.bookstore.model.repositories
import org.springframework.data.jpa.repository.JpaRepository
import ubsocial.com.bookstore.model.entity.Book
interface BookRepository : JpaRepository<Book, Long>
package ubsocial.com.bookstore.controller
import jakarta.validation.Valid
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import ubsocial.com.bookstore.model.entity.Book
import ubsocial.com.bookstore.model.repositories.BookRepository
@RestController
@RequestMapping("/books")
class BookResource(private val bookRepository: BookRepository) {
@GetMapping
fun getAll(): List<Book> = bookRepository.findAll()
@GetMapping("/{id}")
fun getById(@PathVariable id: Long): ResponseEntity<Book> {
val book = bookRepository.findById(id)
return if (book.isPresent) ResponseEntity.ok(book.get())
else ResponseEntity.notFound().build()
}
@PostMapping
fun create(@RequestBody @Valid book: Book): Book = bookRepository.save(book)
@PutMapping("/{id}")
fun update(@PathVariable id: Long, @RequestBody @Valid book: Book): ResponseEntity<Book> {
val optional = bookRepository.findById(id)
if (optional.isEmpty) return ResponseEntity.notFound().build()
val updated = optional.get().copy(
title = book.title,
author = book.author,
published_date = book.published_date,
isbn = book.isbn,
pages = book.pages,
cover = book.cover,
language = book.language
)
return ResponseEntity.ok(bookRepository.save(updated))
}
@DeleteMapping("/{id}")
fun delete(@PathVariable id: Long): ResponseEntity<Void> {
return if (bookRepository.existsById(id)) {
bookRepository.deleteById(id)
ResponseEntity.noContent().build()
} else {
ResponseEntity.notFound().build()
}
}
}
AQUI
{
"title": "O Senhor dos Anéis",
"author": "J.R.R. Tolkien",
"published_date": "1954-07-29",
"isbn": "9780261102385",
"pages": 1178,
"cover": "Ficção",
"language": "Português"
}
{
"title": "O Senhor dos Anéis - Edição Atualizada",
"author": "J.R.R. Tolkien",
"published_date": "1954-07-29",
"isbn": "9780261102385",
"pages": 1178,
"cover": "Ficção",
"language": "Português"
}
AQUI
Elaborado por Mateus Schwede
ubsocial.github.io