devslab-kr/devslab-examples
GitHub: devslab-kr/devslab-examples
Stars: 0 | Forks: 0
# devslab-examples
**English** · [한국어](README.ko.md)
Runnable examples for [devslab-kr](https://github.com/devslab-kr) Spring Boot starters and libraries.
Each subdirectory is an **independent** Spring Boot application with its own Gradle build. Pick one, `cd` into it, and run `./gradlew bootRun`.
## Examples
### easy-paging — Spring Boot 4 (`4.x` line)
Latest active line. Use these if your app is on Spring Boot 4+.
| Demo | Showcases | Maven Central |
| --- | --- | --- |
| [`easy-paging-sb4-demo`](easy-paging-sb4-demo/) | Annotation-driven offset pagination with `@AutoPaginate` (Spring Boot 4 + MyBatis + H2) | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-sb4-keyset-demo`](easy-paging-sb4-keyset-demo/) | Cursor (keyset) pagination with `@KeysetPaginate` — composite `(time, id)` key, stable under writes, no `OFFSET`/`COUNT(*)` | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-sb4-postgres-demo`](easy-paging-sb4-postgres-demo/) | Same starter against **real PostgreSQL** — Docker Compose for `bootRun`, Testcontainers + `@ServiceConnection` for tests, no local DB install | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-sb4-reactive-demo`](easy-paging-sb4-reactive-demo/) | Reactive stack — **WebFlux + R2DBC** via `R2dbcOffsetPagingSupport`. Same JSON envelope as the MVC demos, served as `Mono>` | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) |
### easy-paging — Spring Boot 3 maintenance (`3.x` line)
For apps still on Spring Boot 3.3–3.5. The starter's [`3.x` branch](https://github.com/devslab-kr/easy-paging-spring-boot-starter/tree/3.x) continues to receive SB3 security patches; these demos pin against that line.
| Demo | Showcases | Maven Central |
| --- | --- | --- |
| [`easy-paging-demo`](easy-paging-demo/) | Annotation-driven offset pagination with `@AutoPaginate` (Spring Boot 3 + MyBatis + H2) | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-keyset-demo`](easy-paging-keyset-demo/) | Cursor (keyset) pagination with `@KeysetPaginate` | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-postgres-demo`](easy-paging-postgres-demo/) | Same starter against real PostgreSQL | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-reactive-demo`](easy-paging-reactive-demo/) | Reactive stack — WebFlux + R2DBC | [](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) |
### ssrf-guard
| Demo | Showcases | Maven Central |
| --- | --- | --- |
| [`ssrf-guard-demo`](ssrf-guard-demo/) | SSRF (Server-Side Request Forgery) protection across three Spring HTTP clients (RestClient, RestTemplate, WebClient) — same `UrlPolicy` for all. 15-pattern attack matrix endpoint, Micrometer metrics. | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard) |
| [`ssrf-guard-springai-demo`](ssrf-guard-springai-demo/) | ⭐ **LLM agent SSRF defense (Spring AI).** Wraps every Spring AI `ToolCallback` so URL-shaped tool arguments are validated before the LLM-driven `fetch_url` runs. Fake-LLM driver makes the demo runnable offline (no API key). | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-springai) |
| [`ssrf-guard-langchain4j-demo`](ssrf-guard-langchain4j-demo/) | ⭐ **LLM agent SSRF defense (LangChain4j).** Same story for the other major Java LLM framework — wraps every `ToolExecutor` bean and validates `ToolExecutionRequest.arguments()` JSON before the executor runs. | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-langchain4j) |
| [`ssrf-guard-feign-demo`](ssrf-guard-feign-demo/) | Spring Cloud OpenFeign `RequestInterceptor` — same `UrlPolicy` applied to `@FeignClient` calls. Two `@FeignClient` interfaces (one whitelisted, one not) to show the block path. | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-feign) |
| [`ssrf-guard-jdkhttp-demo`](ssrf-guard-jdkhttp-demo/) | `java.net.http.HttpClient` (Java 11+) wrapper — no Spring required by the library. Three-line wiring in `main()`. | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-jdkhttp) |
| [`ssrf-guard-okhttp-demo`](ssrf-guard-okhttp-demo/) | OkHttp `Interceptor` + `Dns` integration — also no Spring needed. Three-line wiring on `OkHttpClient.Builder`. | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-okhttp) |
| [`ssrf-guard-httpclient5-demo`](ssrf-guard-httpclient5-demo/) | Apache HttpClient 5 — **DNS-time** SSRF gate (`SafeDnsResolver`) + `SafeRedirectStrategy`. Zero wiring code in Spring (module ships its own autoconfig); five-line wiring outside Spring. The TOCTOU-closing approach: validate=connect on the same `InetAddress[]`. | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-httpclient5) |
| [`ssrf-guard-native-image-demo`](ssrf-guard-native-image-demo/) | ⚡ **GraalVM native-image** proof. Pulls `ssrf-guard:3.1.0`, applies the `org.graalvm.buildtools.native` plugin, demonstrates `nativeCompile` produces a working native binary that blocks the same 12-pattern attack matrix as the JVM build. End-to-end verification that ssrf-guard 3.1.0's `RuntimeHintsRegistrar` entries are complete. | [](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard) |
### api-log
| Demo | Showcases | Maven Central |
| --- | --- | --- |
| [`api-log-jpa-demo`](api-log-jpa-demo/) | **JPA backend** — Spring MVC + `RestApiClientUtil` (blocking) + `JpaApiLogWriter`. Reads the logged rows via `ApiLogRepository` (Spring Data JPA). The most common drop-in for Servlet/JPA apps. | [](https://central.sonatype.com/artifact/kr.devslab/api-log-jpa) |
| [`api-log-mybatis-demo`](api-log-mybatis-demo/) | **MyBatis backend** — Spring MVC + `RestApiClientUtil` + `MybatisApiLogWriter`. Uses the bundled `ApiLogMapper` for by-request lookup, plus a custom `ApiLogQueryMapper` (xml) for `recent` / `by-event` queries. For teams already on MyBatis who don't want JPA. | [](https://central.sonatype.com/artifact/kr.devslab/api-log-mybatis) |
| [`api-log-r2dbc-demo`](api-log-r2dbc-demo/) | **R2DBC backend (reactive)** — WebFlux + `ReactiveApiClientUtil` (`Mono`-based) + `R2dbcApiLogWriter`. Reader uses `DatabaseClient` for streaming `Flux`. Entire HTTP path is non-blocking; api-log writes also non-blocking. For WebFlux apps that have no JDBC anywhere on the request path. | [](https://central.sonatype.com/artifact/kr.devslab/api-log-r2dbc) |
### devslab-kit
Spring Boot 4 platform starter — authentication, RBAC + groups + ABAC, multi-tenancy, dynamic menus, audit logging, and an admin REST API, all from auto-configuration. Full docs at [devslab-kit.devslab.kr](https://devslab-kit.devslab.kr).
| Demo | Showcases | Maven Central |
| --- | --- | --- |
| [`devslab-kit-demo`](devslab-kit-demo/) | A plain consumer app with **no platform code of its own** — adding the starter brings up auth, RBAC + ABAC, multi-tenancy, dynamic menus, audit, the first-admin bootstrap, and the admin REST API. PostgreSQL + Redis (distributed cache); Docker Compose for `bootRun`, Testcontainers + `@ServiceConnection` for tests. | [](https://central.sonatype.com/artifact/kr.devslab/devslab-kit-spring-boot-starter) |
## Conventions
- Each demo is a **standalone Gradle project** — its own `settings.gradle.kts`, `build.gradle.kts`, and `gradlew`. Demos do not share a root build, so their dependency versions and JDK targets can drift independently.
- Each demo depends on the **latest stable release** of the starter it showcases (pinned by version in `build.gradle.kts`). Dependabot bumps it on new releases.
- This repo is **not versioned or tagged** — demos are not published artifacts. `main` is the source of truth.
- Each demo has its own `README.md` with quickstart, prerequisites, and a tour of what the starter is doing.
## Adding a new demo
1. Create `-demo/` at the repo root.
2. Copy the layout of an existing demo (e.g. `easy-paging-demo/`) as a template.
3. Add a row to the table above linking to the demo and to its starter on Maven Central.
4. CI auto-detects the new demo from the presence of `build.gradle.kts` — no workflow changes needed.
## CI
Pull requests build only the demos whose files changed. Pushes to `main` build every demo (catches drift from starter version bumps).
标签:域名枚举