Last active
September 17, 2023 15:23
-
-
Save irumiha/c78b84f543e875cba0847f69e933a54d to your computer and use it in GitHub Desktop.
Single-file Spring Boot application. A silly example but it can be done. Run it as `jbang TodoApp.java`. You need the https://www.jbang.dev/ tool installed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//JAVA 17 | |
//DEPS org.springframework.boot:spring-boot-dependencies:3.1.3@pom | |
//DEPS org.springframework.boot:spring-boot-starter-web | |
//DEPS org.springframework.boot:spring-boot-starter-data-jdbc | |
//DEPS com.h2database:h2 | |
package app; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
import org.springframework.context.event.EventListener; | |
import org.springframework.context.event.ContextRefreshedEvent; | |
import org.springframework.data.annotation.Id; | |
import org.springframework.data.jdbc.repository.query.Modifying; | |
import org.springframework.data.jdbc.repository.query.Query; | |
import org.springframework.data.relational.core.mapping.Table; | |
import org.springframework.data.repository.CrudRepository; | |
import org.springframework.data.repository.query.Param; | |
import org.springframework.jdbc.core.JdbcTemplate; | |
import org.springframework.stereotype.Component; | |
import org.springframework.stereotype.Repository; | |
import org.springframework.web.bind.annotation.*; | |
@SpringBootApplication | |
@RestController | |
public class TodoApp { | |
public static void main(String[] args) { | |
SpringApplication.run(TodoApp.class, args); | |
} | |
private final Logger logger = LoggerFactory.getLogger(TodoApp.class); | |
private final TodoRepository todoRepository; | |
TodoApp(TodoRepository todoRepository) { | |
this.todoRepository = todoRepository; | |
} | |
@GetMapping("/todos") | |
Iterable<Todo> todos() { | |
return todoRepository.findAll(); | |
} | |
@PostMapping("/todos") | |
Todo newTodo(@RequestBody TodoCreateCommand todo) { | |
logger.debug("Creating new todo: {}", todo); | |
return todoRepository.save(new Todo(null, todo.description(), todo.done())); | |
} | |
@PostMapping("/todos/{id}/done") | |
Todo markTodoDone(@PathVariable("id") Integer id) { | |
todoRepository.markAsDone(id); | |
return todoRepository.findById(id).orElseThrow(); | |
} | |
@PostMapping("/todos/{id}/not-done") | |
Todo markTodoNotDone(@PathVariable("id") Integer id) { | |
todoRepository.markAsNotDone(id); | |
return todoRepository.findById(id).orElseThrow(); | |
} | |
} | |
@Component | |
record StartupAppListener(JdbcTemplate jdbc) { | |
@EventListener | |
public void onApplicationEvent(ContextRefreshedEvent event) { | |
jdbc.execute(""" | |
CREATE TABLE IF NOT EXISTS todos | |
( | |
id INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT, | |
description TEXT NOT NULL, | |
done BOOLEAN NOT NULL DEFAULT 0 | |
); | |
"""); | |
} | |
} | |
record TodoCreateCommand(String description, Boolean done) { | |
} | |
@Table("TODOS") | |
record Todo(@Id Integer id, String description, Boolean done) { | |
} | |
@Repository | |
interface TodoRepository extends CrudRepository<Todo, Integer> { | |
@Modifying | |
@Query("update todos set done = true where id=:id") | |
void markAsDone(@Param("id") Integer id); | |
@Modifying | |
@Query("update todos set done = false where id=:id") | |
void markAsNotDone(@Param("id") Integer id); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment