@ngxtm/devkit 3.4.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/rules/README.md +141 -0
- package/rules/dart/best-practices/SKILL.md +23 -0
- package/rules/dart/language/SKILL.md +52 -0
- package/rules/dart/tooling/SKILL.md +43 -0
- package/rules/dotnet/aspnet-core/SKILL.md +92 -0
- package/rules/dotnet/aspnet-core/references/REFERENCE.md +335 -0
- package/rules/dotnet/best-practices/SKILL.md +101 -0
- package/rules/dotnet/best-practices/references/REFERENCE.md +256 -0
- package/rules/dotnet/blazor/SKILL.md +146 -0
- package/rules/dotnet/blazor/references/REFERENCE.md +392 -0
- package/rules/dotnet/language/SKILL.md +82 -0
- package/rules/dotnet/language/references/REFERENCE.md +222 -0
- package/rules/dotnet/patterns.rule.md +388 -0
- package/rules/dotnet/razor-pages/SKILL.md +124 -0
- package/rules/dotnet/razor-pages/references/REFERENCE.md +321 -0
- package/rules/dotnet/security/SKILL.md +89 -0
- package/rules/dotnet/security/references/REFERENCE.md +295 -0
- package/rules/dotnet/tooling/SKILL.md +92 -0
- package/rules/dotnet/tooling/references/REFERENCE.md +300 -0
- package/rules/flutter/auto-route-navigation/SKILL.md +43 -0
- package/rules/flutter/auto-route-navigation/references/REFERENCE.md +19 -0
- package/rules/flutter/auto-route-navigation/references/router-config.md +62 -0
- package/rules/flutter/bloc-state-management/SKILL.md +64 -0
- package/rules/flutter/bloc-state-management/references/REFERENCE.md +20 -0
- package/rules/flutter/bloc-state-management/references/auth-bloc-example.md +52 -0
- package/rules/flutter/bloc-state-management/references/equatable-usage.md +56 -0
- package/rules/flutter/bloc-state-management/references/property-based-state.md +68 -0
- package/rules/flutter/bloc.rule.md +76 -0
- package/rules/flutter/cicd/SKILL.md +48 -0
- package/rules/flutter/cicd/references/advanced-workflow.md +66 -0
- package/rules/flutter/cicd/references/fastlane.md +139 -0
- package/rules/flutter/cicd/references/github-actions.md +59 -0
- package/rules/flutter/dependency-injection/SKILL.md +42 -0
- package/rules/flutter/dependency-injection/references/REFERENCE.md +15 -0
- package/rules/flutter/dependency-injection/references/modules.md +37 -0
- package/rules/flutter/error-handling/SKILL.md +32 -0
- package/rules/flutter/error-handling/references/REFERENCE.md +19 -0
- package/rules/flutter/error-handling/references/error-mapping.md +31 -0
- package/rules/flutter/feature-based-clean-architecture/SKILL.md +46 -0
- package/rules/flutter/feature-based-clean-architecture/references/REFERENCE.md +14 -0
- package/rules/flutter/feature-based-clean-architecture/references/folder-structure.md +36 -0
- package/rules/flutter/getx-navigation/SKILL.md +70 -0
- package/rules/flutter/getx-navigation/references/app-pages.md +40 -0
- package/rules/flutter/getx-navigation/references/middleware-example.md +29 -0
- package/rules/flutter/getx-state-management/SKILL.md +76 -0
- package/rules/flutter/getx-state-management/references/binding-example.md +32 -0
- package/rules/flutter/getx-state-management/references/reactive-vs-simple.md +39 -0
- package/rules/flutter/go-router-navigation/SKILL.md +57 -0
- package/rules/flutter/idiomatic-flutter/SKILL.md +20 -0
- package/rules/flutter/layer-based-clean-architecture/SKILL.md +50 -0
- package/rules/flutter/layer-based-clean-architecture/references/REFERENCE.md +60 -0
- package/rules/flutter/layer-based-clean-architecture/references/repository-mapping.md +50 -0
- package/rules/flutter/localization/SKILL.md +50 -0
- package/rules/flutter/localization/references/REFERENCE.md +48 -0
- package/rules/flutter/localization/references/sheet-loader.md +33 -0
- package/rules/flutter/navigator-v1-navigation/SKILL.md +71 -0
- package/rules/flutter/navigator-v1-navigation/references/on-generate-route.md +48 -0
- package/rules/flutter/performance/SKILL.md +24 -0
- package/rules/flutter/retrofit-networking/SKILL.md +51 -0
- package/rules/flutter/retrofit-networking/references/REFERENCE.md +19 -0
- package/rules/flutter/retrofit-networking/references/token-refresh.md +40 -0
- package/rules/flutter/riverpod-state-management/SKILL.md +53 -0
- package/rules/flutter/riverpod-state-management/references/architecture.md +124 -0
- package/rules/flutter/riverpod-state-management/references/best-practices.md +89 -0
- package/rules/flutter/riverpod-state-management/references/testing.md +73 -0
- package/rules/flutter/riverpod.rule.md +78 -0
- package/rules/flutter/security/SKILL.md +33 -0
- package/rules/flutter/security/references/REFERENCE.md +15 -0
- package/rules/flutter/security/references/network-security.md +28 -0
- package/rules/flutter/testing/SKILL.md +44 -0
- package/rules/flutter/testing/references/REFERENCE.md +21 -0
- package/rules/flutter/testing/references/bloc-testing.md +38 -0
- package/rules/flutter/testing/references/integration-testing.md +128 -0
- package/rules/flutter/testing/references/robot-pattern.md +82 -0
- package/rules/flutter/testing/references/unit-testing.md +130 -0
- package/rules/flutter/testing/references/widget-testing.md +120 -0
- package/rules/flutter/widgets/SKILL.md +37 -0
- package/rules/golang/chi-router/SKILL.md +219 -0
- package/rules/golang/chi-router/references/REFERENCE.md +13 -0
- package/rules/golang/chi-router/references/routing-patterns.md +205 -0
- package/rules/golang/cobra-cli/SKILL.md +227 -0
- package/rules/golang/cobra-cli/references/REFERENCE.md +13 -0
- package/rules/golang/cobra-cli/references/command-patterns.md +224 -0
- package/rules/golang/core/SKILL.md +210 -0
- package/rules/golang/core/references/REFERENCE.md +14 -0
- package/rules/golang/core/references/concurrency-patterns.md +114 -0
- package/rules/golang/core/references/error-handling.md +87 -0
- package/rules/golang/echo-framework/SKILL.md +215 -0
- package/rules/golang/echo-framework/references/REFERENCE.md +14 -0
- package/rules/golang/echo-framework/references/middleware-patterns.md +141 -0
- package/rules/golang/echo-framework/references/routing-patterns.md +140 -0
- package/rules/golang/ent-orm/SKILL.md +239 -0
- package/rules/golang/ent-orm/references/REFERENCE.md +13 -0
- package/rules/golang/ent-orm/references/schema-patterns.md +255 -0
- package/rules/golang/fiber-framework/SKILL.md +196 -0
- package/rules/golang/fiber-framework/references/REFERENCE.md +13 -0
- package/rules/golang/fiber-framework/references/routing-patterns.md +191 -0
- package/rules/golang/gin-framework/SKILL.md +205 -0
- package/rules/golang/gin-framework/references/REFERENCE.md +14 -0
- package/rules/golang/gin-framework/references/middleware-patterns.md +119 -0
- package/rules/golang/gorm-orm/SKILL.md +196 -0
- package/rules/golang/gorm-orm/references/REFERENCE.md +14 -0
- package/rules/golang/gorm-orm/references/model-definitions.md +167 -0
- package/rules/golang/gorm-orm/references/query-patterns.md +161 -0
- package/rules/golang/grpc/SKILL.md +231 -0
- package/rules/golang/grpc/references/REFERENCE.md +13 -0
- package/rules/golang/grpc/references/service-patterns.md +276 -0
- package/rules/golang/testify/SKILL.md +239 -0
- package/rules/golang/testify/references/REFERENCE.md +13 -0
- package/rules/golang/testify/references/assert-patterns.md +170 -0
- package/rules/golang/validator/SKILL.md +234 -0
- package/rules/golang/validator/references/REFERENCE.md +13 -0
- package/rules/golang/validator/references/validation-tags.md +211 -0
- package/rules/golang/viper-config/SKILL.md +244 -0
- package/rules/golang/viper-config/references/REFERENCE.md +13 -0
- package/rules/golang/viper-config/references/config-loading.md +181 -0
- package/rules/golang/wire-di/SKILL.md +243 -0
- package/rules/golang/wire-di/references/REFERENCE.md +13 -0
- package/rules/golang/wire-di/references/provider-patterns.md +193 -0
- package/rules/golang/zap-logging/SKILL.md +203 -0
- package/rules/golang/zap-logging/references/REFERENCE.md +13 -0
- package/rules/golang/zap-logging/references/logger-config.md +165 -0
- package/rules/java/build-gradle/SKILL.md +92 -0
- package/rules/java/build-gradle/references/REFERENCE.md +14 -0
- package/rules/java/build-gradle/references/kotlin-dsl.md +118 -0
- package/rules/java/build-gradle/references/task-configuration.md +132 -0
- package/rules/java/build-maven/SKILL.md +86 -0
- package/rules/java/build-maven/references/REFERENCE.md +14 -0
- package/rules/java/build-maven/references/dependency-management.md +111 -0
- package/rules/java/build-maven/references/lifecycle-phases.md +114 -0
- package/rules/java/graalvm-native/SKILL.md +105 -0
- package/rules/java/graalvm-native/references/REFERENCE.md +12 -0
- package/rules/java/java-collections-streams/SKILL.md +148 -0
- package/rules/java/java-collections-streams/references/REFERENCE.md +15 -0
- package/rules/java/java-collections-streams/references/collectors-patterns.md +178 -0
- package/rules/java/java-collections-streams/references/stream-pipelines.md +165 -0
- package/rules/java/java-concurrency/SKILL.md +187 -0
- package/rules/java/java-concurrency/references/REFERENCE.md +17 -0
- package/rules/java/java-concurrency/references/completable-future.md +165 -0
- package/rules/java/java-concurrency/references/executor-patterns.md +176 -0
- package/rules/java/java-concurrency/references/virtual-threads.md +190 -0
- package/rules/java/java-core-language/SKILL.md +121 -0
- package/rules/java/java-core-language/references/REFERENCE.md +15 -0
- package/rules/java/java-core-language/references/jvm-memory-model.md +160 -0
- package/rules/java/java-core-language/references/modern-java-features.md +168 -0
- package/rules/java/java-project-structure/SKILL.md +195 -0
- package/rules/java/java-project-structure/references/REFERENCE.md +15 -0
- package/rules/java/java-project-structure/references/maven-project-layout.md +199 -0
- package/rules/java/java-project-structure/references/module-system.md +159 -0
- package/rules/java/micronaut-core/SKILL.md +99 -0
- package/rules/java/micronaut-core/references/REFERENCE.md +12 -0
- package/rules/java/micronaut-reactive/SKILL.md +68 -0
- package/rules/java/micronaut-reactive/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-core/SKILL.md +85 -0
- package/rules/java/quarkus-core/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-reactive/SKILL.md +67 -0
- package/rules/java/quarkus-reactive/references/REFERENCE.md +12 -0
- package/rules/java/spring-batch/SKILL.md +102 -0
- package/rules/java/spring-batch/references/REFERENCE.md +12 -0
- package/rules/java/spring-boot-architecture/SKILL.md +206 -0
- package/rules/java/spring-boot-architecture/references/REFERENCE.md +15 -0
- package/rules/java/spring-boot-architecture/references/auto-configuration.md +158 -0
- package/rules/java/spring-boot-architecture/references/configuration-properties.md +202 -0
- package/rules/java/spring-boot-web/SKILL.md +217 -0
- package/rules/java/spring-boot-web/references/REFERENCE.md +17 -0
- package/rules/java/spring-cloud/SKILL.md +109 -0
- package/rules/java/spring-cloud/references/REFERENCE.md +13 -0
- package/rules/java/spring-data-jpa/SKILL.md +241 -0
- package/rules/java/spring-data-jpa/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/SKILL.md +161 -0
- package/rules/java/spring-security/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/references/jwt-auth-flow.md +213 -0
- package/rules/java/testing-junit-mockito/SKILL.md +135 -0
- package/rules/java/testing-junit-mockito/references/REFERENCE.md +15 -0
- package/rules/java/testing-junit-mockito/references/junit5-patterns.md +159 -0
- package/rules/java/testing-junit-mockito/references/mockito-patterns.md +148 -0
- package/rules/java/testing-junit-mockito/references/spring-boot-testing.md +152 -0
- package/rules/javascript/best-practices/SKILL.md +64 -0
- package/rules/javascript/best-practices/references/REFERENCE.md +91 -0
- package/rules/javascript/language/SKILL.md +71 -0
- package/rules/javascript/language/references/REFERENCE.md +106 -0
- package/rules/javascript/tooling/SKILL.md +60 -0
- package/rules/javascript/tooling/references/REFERENCE.md +107 -0
- package/rules/metadata.json +54 -0
- package/rules/nestjs/api-standards/SKILL.md +47 -0
- package/rules/nestjs/api-standards/references/pagination-wrapper.md +87 -0
- package/rules/nestjs/architecture/SKILL.md +68 -0
- package/rules/nestjs/architecture/references/dynamic-module.md +53 -0
- package/rules/nestjs/caching/SKILL.md +51 -0
- package/rules/nestjs/caching/references/REFERENCE.md +13 -0
- package/rules/nestjs/caching/references/cache-patterns.md +183 -0
- package/rules/nestjs/configuration/SKILL.md +41 -0
- package/rules/nestjs/configuration/references/REFERENCE.md +13 -0
- package/rules/nestjs/configuration/references/config-patterns.md +184 -0
- package/rules/nestjs/controllers-services/SKILL.md +63 -0
- package/rules/nestjs/controllers-services/references/REFERENCE.md +14 -0
- package/rules/nestjs/controllers-services/references/controller-patterns.md +119 -0
- package/rules/nestjs/controllers-services/references/service-patterns.md +129 -0
- package/rules/nestjs/database/SKILL.md +102 -0
- package/rules/nestjs/database/references/REFERENCE.md +14 -0
- package/rules/nestjs/database/references/typeorm-patterns.md +156 -0
- package/rules/nestjs/deployment/SKILL.md +36 -0
- package/rules/nestjs/deployment/references/REFERENCE.md +13 -0
- package/rules/nestjs/deployment/references/deployment-patterns.md +140 -0
- package/rules/nestjs/documentation/SKILL.md +64 -0
- package/rules/nestjs/documentation/references/REFERENCE.md +13 -0
- package/rules/nestjs/documentation/references/swagger-patterns.md +139 -0
- package/rules/nestjs/error-handling/SKILL.md +55 -0
- package/rules/nestjs/error-handling/references/REFERENCE.md +13 -0
- package/rules/nestjs/error-handling/references/exception-filters.md +152 -0
- package/rules/nestjs/file-uploads/SKILL.md +35 -0
- package/rules/nestjs/file-uploads/references/REFERENCE.md +13 -0
- package/rules/nestjs/file-uploads/references/upload-patterns.md +125 -0
- package/rules/nestjs/observability/SKILL.md +39 -0
- package/rules/nestjs/observability/references/REFERENCE.md +13 -0
- package/rules/nestjs/observability/references/logging-metrics.md +175 -0
- package/rules/nestjs/performance/SKILL.md +60 -0
- package/rules/nestjs/performance/references/REFERENCE.md +13 -0
- package/rules/nestjs/performance/references/performance-patterns.md +107 -0
- package/rules/nestjs/real-time/SKILL.md +45 -0
- package/rules/nestjs/real-time/references/REFERENCE.md +13 -0
- package/rules/nestjs/real-time/references/websocket-patterns.md +121 -0
- package/rules/nestjs/scheduling/SKILL.md +39 -0
- package/rules/nestjs/scheduling/references/REFERENCE.md +13 -0
- package/rules/nestjs/scheduling/references/scheduling-patterns.md +137 -0
- package/rules/nestjs/search/SKILL.md +41 -0
- package/rules/nestjs/search/references/REFERENCE.md +13 -0
- package/rules/nestjs/search/references/search-patterns.md +137 -0
- package/rules/nestjs/security/SKILL.md +87 -0
- package/rules/nestjs/security/references/REFERENCE.md +14 -0
- package/rules/nestjs/security/references/authentication.md +151 -0
- package/rules/nestjs/testing/SKILL.md +40 -0
- package/rules/nestjs/testing/references/REFERENCE.md +14 -0
- package/rules/nestjs/testing/references/unit-testing.md +179 -0
- package/rules/nestjs/transport/SKILL.md +45 -0
- package/rules/nestjs/transport/references/REFERENCE.md +13 -0
- package/rules/nestjs/transport/references/microservices-patterns.md +170 -0
- package/rules/nextjs/app-router/SKILL.md +46 -0
- package/rules/nextjs/app-router/references/REFERENCE.md +14 -0
- package/rules/nextjs/app-router/references/routing-patterns.md +182 -0
- package/rules/nextjs/architecture/SKILL.md +44 -0
- package/rules/nextjs/architecture/references/fsd-structure.md +77 -0
- package/rules/nextjs/authentication/SKILL.md +29 -0
- package/rules/nextjs/authentication/references/auth-implementation.md +73 -0
- package/rules/nextjs/caching/SKILL.md +66 -0
- package/rules/nextjs/caching/references/REFERENCE.md +13 -0
- package/rules/nextjs/caching/references/cache-strategies.md +168 -0
- package/rules/nextjs/data-access-layer/SKILL.md +33 -0
- package/rules/nextjs/data-access-layer/references/patterns.md +66 -0
- package/rules/nextjs/data-fetching/SKILL.md +59 -0
- package/rules/nextjs/data-fetching/references/REFERENCE.md +13 -0
- package/rules/nextjs/data-fetching/references/fetch-patterns.md +160 -0
- package/rules/nextjs/internationalization/SKILL.md +105 -0
- package/rules/nextjs/internationalization/references/REFERENCE.md +13 -0
- package/rules/nextjs/internationalization/references/i18n-patterns.md +180 -0
- package/rules/nextjs/optimization/SKILL.md +64 -0
- package/rules/nextjs/optimization/references/REFERENCE.md +13 -0
- package/rules/nextjs/optimization/references/optimization-patterns.md +190 -0
- package/rules/nextjs/rendering/SKILL.md +91 -0
- package/rules/nextjs/rendering/references/REFERENCE.md +13 -0
- package/rules/nextjs/rendering/references/rendering-modes.md +163 -0
- package/rules/nextjs/server-actions/SKILL.md +46 -0
- package/rules/nextjs/server-actions/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-actions/references/action-patterns.md +188 -0
- package/rules/nextjs/server-components/SKILL.md +52 -0
- package/rules/nextjs/server-components/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-components/references/component-patterns.md +175 -0
- package/rules/nextjs/state-management/SKILL.md +73 -0
- package/rules/nextjs/state-management/references/REFERENCE.md +13 -0
- package/rules/nextjs/state-management/references/state-patterns.md +218 -0
- package/rules/nextjs/styling/SKILL.md +31 -0
- package/rules/nextjs/styling/references/implementation.md +56 -0
- package/rules/react/component-patterns/SKILL.md +66 -0
- package/rules/react/component-patterns/references/REFERENCE.md +126 -0
- package/rules/react/hooks/SKILL.md +60 -0
- package/rules/react/hooks/references/REFERENCE.md +132 -0
- package/rules/react/hooks.rule.md +79 -0
- package/rules/react/performance/SKILL.md +69 -0
- package/rules/react/performance/references/REFERENCE.md +143 -0
- package/rules/react/security/SKILL.md +46 -0
- package/rules/react/security/references/REFERENCE.md +170 -0
- package/rules/react/state-management/SKILL.md +56 -0
- package/rules/react/state-management/references/REFERENCE.md +137 -0
- package/rules/react/testing/SKILL.md +45 -0
- package/rules/react/testing/references/REFERENCE.md +149 -0
- package/rules/react/tooling/SKILL.md +39 -0
- package/rules/react/typescript/SKILL.md +53 -0
- package/rules/rust/actix-web/SKILL.md +160 -0
- package/rules/rust/actix-web/references/REFERENCE.md +13 -0
- package/rules/rust/actix-web/references/handler-patterns.md +198 -0
- package/rules/rust/async-graphql/SKILL.md +228 -0
- package/rules/rust/async-graphql/references/REFERENCE.md +13 -0
- package/rules/rust/async-graphql/references/schema-patterns.md +215 -0
- package/rules/rust/axum/SKILL.md +161 -0
- package/rules/rust/axum/references/REFERENCE.md +14 -0
- package/rules/rust/axum/references/handler-patterns.md +97 -0
- package/rules/rust/bevy/SKILL.md +206 -0
- package/rules/rust/bevy/references/REFERENCE.md +13 -0
- package/rules/rust/bevy/references/ecs-patterns.md +226 -0
- package/rules/rust/clap/SKILL.md +217 -0
- package/rules/rust/clap/references/REFERENCE.md +13 -0
- package/rules/rust/clap/references/derive-patterns.md +205 -0
- package/rules/rust/core/SKILL.md +154 -0
- package/rules/rust/core/references/REFERENCE.md +14 -0
- package/rules/rust/core/references/error-handling.md +92 -0
- package/rules/rust/diesel-orm/SKILL.md +176 -0
- package/rules/rust/diesel-orm/references/REFERENCE.md +13 -0
- package/rules/rust/diesel-orm/references/schema-patterns.md +206 -0
- package/rules/rust/rocket/SKILL.md +182 -0
- package/rules/rust/rocket/references/REFERENCE.md +13 -0
- package/rules/rust/rocket/references/handler-patterns.md +209 -0
- package/rules/rust/sea-orm/SKILL.md +230 -0
- package/rules/rust/sea-orm/references/REFERENCE.md +13 -0
- package/rules/rust/sea-orm/references/entity-patterns.md +221 -0
- package/rules/rust/serde-serialization/SKILL.md +150 -0
- package/rules/rust/serde-serialization/references/REFERENCE.md +13 -0
- package/rules/rust/serde-serialization/references/serialization-patterns.md +199 -0
- package/rules/rust/sqlx-database/SKILL.md +140 -0
- package/rules/rust/sqlx-database/references/REFERENCE.md +13 -0
- package/rules/rust/sqlx-database/references/query-patterns.md +210 -0
- package/rules/rust/tauri/SKILL.md +180 -0
- package/rules/rust/tauri/references/REFERENCE.md +13 -0
- package/rules/rust/tauri/references/command-patterns.md +209 -0
- package/rules/rust/tokio-runtime/SKILL.md +167 -0
- package/rules/rust/tokio-runtime/references/REFERENCE.md +14 -0
- package/rules/rust/tokio-runtime/references/async-patterns.md +137 -0
- package/rules/rust/tokio-runtime/references/synchronization.md +152 -0
- package/rules/rust/tonic/SKILL.md +231 -0
- package/rules/rust/tonic/references/REFERENCE.md +13 -0
- package/rules/rust/tonic/references/service-patterns.md +213 -0
- package/rules/rust/tracing/SKILL.md +214 -0
- package/rules/rust/tracing/references/REFERENCE.md +13 -0
- package/rules/rust/tracing/references/instrumentation.md +187 -0
- package/rules/typescript/best-practices/SKILL.md +108 -0
- package/rules/typescript/best-practices/references/REFERENCE.md +68 -0
- package/rules/typescript/language/SKILL.md +72 -0
- package/rules/typescript/language/references/REFERENCE.md +67 -0
- package/rules/typescript/patterns.rule.md +85 -0
- package/rules/typescript/security/SKILL.md +59 -0
- package/rules/typescript/security/references/REFERENCE.md +113 -0
- package/rules/typescript/tooling/SKILL.md +52 -0
- package/rules/typescript/tooling/references/REFERENCE.md +110 -0
- package/skills/learn/SKILL.md +476 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Spring Boot Auto-Configuration
|
|
2
|
+
|
|
3
|
+
## Custom Auto-Configuration
|
|
4
|
+
|
|
5
|
+
```java
|
|
6
|
+
// 1. Create auto-configuration class
|
|
7
|
+
@AutoConfiguration
|
|
8
|
+
@ConditionalOnClass(MyService.class)
|
|
9
|
+
@EnableConfigurationProperties(MyProperties.class)
|
|
10
|
+
public class MyAutoConfiguration {
|
|
11
|
+
|
|
12
|
+
@Bean
|
|
13
|
+
@ConditionalOnMissingBean
|
|
14
|
+
public MyService myService(MyProperties properties) {
|
|
15
|
+
return new MyServiceImpl(properties);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@Bean
|
|
19
|
+
@ConditionalOnProperty(
|
|
20
|
+
prefix = "my.feature",
|
|
21
|
+
name = "enabled",
|
|
22
|
+
havingValue = "true",
|
|
23
|
+
matchIfMissing = false
|
|
24
|
+
)
|
|
25
|
+
public FeatureService featureService() {
|
|
26
|
+
return new FeatureServiceImpl();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 2. Register in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
|
|
31
|
+
// com.example.autoconfigure.MyAutoConfiguration
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Conditional Annotations
|
|
35
|
+
|
|
36
|
+
```java
|
|
37
|
+
// Property conditions
|
|
38
|
+
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
|
|
39
|
+
@ConditionalOnProperty(name = "feature.enabled", matchIfMissing = true)
|
|
40
|
+
|
|
41
|
+
// Class conditions
|
|
42
|
+
@ConditionalOnClass(DataSource.class)
|
|
43
|
+
@ConditionalOnMissingClass("org.mongodb.Driver")
|
|
44
|
+
|
|
45
|
+
// Bean conditions
|
|
46
|
+
@ConditionalOnBean(DataSource.class)
|
|
47
|
+
@ConditionalOnMissingBean(MyService.class)
|
|
48
|
+
@ConditionalOnSingleCandidate(DataSource.class)
|
|
49
|
+
|
|
50
|
+
// Resource conditions
|
|
51
|
+
@ConditionalOnResource(resources = "classpath:schema.sql")
|
|
52
|
+
|
|
53
|
+
// Web conditions
|
|
54
|
+
@ConditionalOnWebApplication
|
|
55
|
+
@ConditionalOnNotWebApplication
|
|
56
|
+
@ConditionalOnWebApplication(type = Type.SERVLET)
|
|
57
|
+
@ConditionalOnWebApplication(type = Type.REACTIVE)
|
|
58
|
+
|
|
59
|
+
// Expression conditions
|
|
60
|
+
@ConditionalOnExpression("${feature.a.enabled} and ${feature.b.enabled}")
|
|
61
|
+
|
|
62
|
+
// Cloud platform
|
|
63
|
+
@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Ordering Auto-Configuration
|
|
67
|
+
|
|
68
|
+
```java
|
|
69
|
+
@AutoConfiguration(
|
|
70
|
+
after = DataSourceAutoConfiguration.class,
|
|
71
|
+
before = JpaRepositoriesAutoConfiguration.class
|
|
72
|
+
)
|
|
73
|
+
public class MyAutoConfiguration {
|
|
74
|
+
// Runs after DataSource, before JPA repositories
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// With @AutoConfigureOrder (for non-auto-config)
|
|
78
|
+
@Configuration
|
|
79
|
+
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
|
|
80
|
+
public class EarlyConfiguration {}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Creating Starters
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
my-spring-boot-starter/
|
|
87
|
+
├── pom.xml
|
|
88
|
+
├── src/main/java/
|
|
89
|
+
│ └── com/example/autoconfigure/
|
|
90
|
+
│ ├── MyAutoConfiguration.java
|
|
91
|
+
│ └── MyProperties.java
|
|
92
|
+
└── src/main/resources/
|
|
93
|
+
└── META-INF/
|
|
94
|
+
├── spring/
|
|
95
|
+
│ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
|
|
96
|
+
└── additional-spring-configuration-metadata.json
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**AutoConfiguration.imports:**
|
|
100
|
+
```
|
|
101
|
+
com.example.autoconfigure.MyAutoConfiguration
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Configuration metadata (IDE support):**
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"properties": [
|
|
108
|
+
{
|
|
109
|
+
"name": "my.service.enabled",
|
|
110
|
+
"type": "java.lang.Boolean",
|
|
111
|
+
"description": "Enable MyService auto-configuration.",
|
|
112
|
+
"defaultValue": true
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"name": "my.service.timeout",
|
|
116
|
+
"type": "java.time.Duration",
|
|
117
|
+
"description": "Connection timeout.",
|
|
118
|
+
"defaultValue": "30s"
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Debugging Auto-Configuration
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
# Enable debug logging
|
|
128
|
+
debug: true
|
|
129
|
+
|
|
130
|
+
# Or specific logging
|
|
131
|
+
logging:
|
|
132
|
+
level:
|
|
133
|
+
org.springframework.boot.autoconfigure: DEBUG
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# Actuator endpoint
|
|
138
|
+
GET /actuator/conditions
|
|
139
|
+
|
|
140
|
+
# Shows:
|
|
141
|
+
# - positiveMatches: Conditions that matched
|
|
142
|
+
# - negativeMatches: Conditions that didn't match
|
|
143
|
+
# - unconditionalClasses: Auto-configs without conditions
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Disabling Auto-Configuration
|
|
147
|
+
|
|
148
|
+
```java
|
|
149
|
+
@SpringBootApplication(exclude = {
|
|
150
|
+
DataSourceAutoConfiguration.class,
|
|
151
|
+
HibernateJpaAutoConfiguration.class
|
|
152
|
+
})
|
|
153
|
+
public class Application {}
|
|
154
|
+
|
|
155
|
+
// Or via properties
|
|
156
|
+
spring.autoconfigure.exclude=\
|
|
157
|
+
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
|
|
158
|
+
```
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Configuration Properties
|
|
2
|
+
|
|
3
|
+
## Type-Safe Configuration
|
|
4
|
+
|
|
5
|
+
```java
|
|
6
|
+
// Using record (immutable, recommended)
|
|
7
|
+
@ConfigurationProperties(prefix = "app")
|
|
8
|
+
@Validated
|
|
9
|
+
public record AppProperties(
|
|
10
|
+
@NotBlank String name,
|
|
11
|
+
@NotNull Duration timeout,
|
|
12
|
+
@Min(1) @Max(100) int maxRetries,
|
|
13
|
+
@Valid ServerProperties server,
|
|
14
|
+
Map<String, String> metadata,
|
|
15
|
+
List<String> allowedOrigins
|
|
16
|
+
) {
|
|
17
|
+
public record ServerProperties(
|
|
18
|
+
String host,
|
|
19
|
+
@Min(1) @Max(65535) int port,
|
|
20
|
+
boolean ssl
|
|
21
|
+
) {}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Using class (when mutability needed)
|
|
25
|
+
@ConfigurationProperties(prefix = "app")
|
|
26
|
+
@Validated
|
|
27
|
+
public class AppProperties {
|
|
28
|
+
@NotBlank
|
|
29
|
+
private String name;
|
|
30
|
+
|
|
31
|
+
@DurationUnit(ChronoUnit.SECONDS)
|
|
32
|
+
private Duration timeout = Duration.ofSeconds(30);
|
|
33
|
+
|
|
34
|
+
// getters and setters
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Binding Configuration
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
# application.yml
|
|
42
|
+
app:
|
|
43
|
+
name: My Application
|
|
44
|
+
timeout: 30s # Duration
|
|
45
|
+
max-retries: 3 # kebab-case → camelCase
|
|
46
|
+
server:
|
|
47
|
+
host: localhost
|
|
48
|
+
port: 8080
|
|
49
|
+
ssl: true
|
|
50
|
+
metadata:
|
|
51
|
+
version: "1.0"
|
|
52
|
+
env: production
|
|
53
|
+
allowed-origins:
|
|
54
|
+
- http://localhost:3000
|
|
55
|
+
- https://example.com
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Relaxed Binding
|
|
59
|
+
|
|
60
|
+
Spring Boot supports multiple formats:
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
# All equivalent for "firstName" property
|
|
64
|
+
app:
|
|
65
|
+
firstName: John # standard camel case
|
|
66
|
+
first-name: John # kebab-case (recommended in YAML)
|
|
67
|
+
first_name: John # underscore notation
|
|
68
|
+
FIRST_NAME: John # uppercase (environment variables)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Validation
|
|
72
|
+
|
|
73
|
+
```java
|
|
74
|
+
@ConfigurationProperties(prefix = "app.database")
|
|
75
|
+
@Validated
|
|
76
|
+
public record DatabaseProperties(
|
|
77
|
+
@NotBlank String url,
|
|
78
|
+
@NotBlank String username,
|
|
79
|
+
@NotBlank String password,
|
|
80
|
+
@Min(1) @Max(100) int poolSize,
|
|
81
|
+
@DurationMin(seconds = 1) @DurationMax(minutes = 5) Duration connectionTimeout
|
|
82
|
+
) {}
|
|
83
|
+
|
|
84
|
+
// Custom validation
|
|
85
|
+
public record SecurityProperties(
|
|
86
|
+
@NotBlank String secretKey
|
|
87
|
+
) {
|
|
88
|
+
public SecurityProperties {
|
|
89
|
+
if (secretKey.length() < 32) {
|
|
90
|
+
throw new IllegalArgumentException("Secret key must be at least 32 characters");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Nested Properties
|
|
97
|
+
|
|
98
|
+
```java
|
|
99
|
+
@ConfigurationProperties(prefix = "app")
|
|
100
|
+
public record AppProperties(
|
|
101
|
+
@NestedConfigurationProperty
|
|
102
|
+
DatabaseProperties database,
|
|
103
|
+
|
|
104
|
+
@NestedConfigurationProperty
|
|
105
|
+
CacheProperties cache,
|
|
106
|
+
|
|
107
|
+
Map<String, ServiceProperties> services
|
|
108
|
+
) {
|
|
109
|
+
public record DatabaseProperties(
|
|
110
|
+
String url,
|
|
111
|
+
String username
|
|
112
|
+
) {}
|
|
113
|
+
|
|
114
|
+
public record CacheProperties(
|
|
115
|
+
Duration ttl,
|
|
116
|
+
int maxSize
|
|
117
|
+
) {}
|
|
118
|
+
|
|
119
|
+
public record ServiceProperties(
|
|
120
|
+
String url,
|
|
121
|
+
Duration timeout
|
|
122
|
+
) {}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
app:
|
|
128
|
+
database:
|
|
129
|
+
url: jdbc:postgresql://localhost/db
|
|
130
|
+
username: admin
|
|
131
|
+
cache:
|
|
132
|
+
ttl: 5m
|
|
133
|
+
max-size: 1000
|
|
134
|
+
services:
|
|
135
|
+
user-service:
|
|
136
|
+
url: http://users:8080
|
|
137
|
+
timeout: 10s
|
|
138
|
+
order-service:
|
|
139
|
+
url: http://orders:8080
|
|
140
|
+
timeout: 30s
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Constructor Binding
|
|
144
|
+
|
|
145
|
+
```java
|
|
146
|
+
// Immutable with constructor binding (default for records)
|
|
147
|
+
@ConfigurationProperties(prefix = "app")
|
|
148
|
+
public record AppProperties(
|
|
149
|
+
String name,
|
|
150
|
+
Duration timeout,
|
|
151
|
+
ServerProperties server
|
|
152
|
+
) {
|
|
153
|
+
// Default values via compact constructor
|
|
154
|
+
public AppProperties {
|
|
155
|
+
if (timeout == null) {
|
|
156
|
+
timeout = Duration.ofSeconds(30);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
public record ServerProperties(String host, int port) {
|
|
161
|
+
public ServerProperties {
|
|
162
|
+
if (port == 0) {
|
|
163
|
+
port = 8080;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Enabling Configuration Properties
|
|
171
|
+
|
|
172
|
+
```java
|
|
173
|
+
// Option 1: On configuration class
|
|
174
|
+
@Configuration
|
|
175
|
+
@EnableConfigurationProperties(AppProperties.class)
|
|
176
|
+
public class AppConfig {}
|
|
177
|
+
|
|
178
|
+
// Option 2: Component scan (not recommended)
|
|
179
|
+
@ConfigurationProperties(prefix = "app")
|
|
180
|
+
@Component // Scanned automatically
|
|
181
|
+
public class AppProperties {}
|
|
182
|
+
|
|
183
|
+
// Option 3: ConfigurationPropertiesScan
|
|
184
|
+
@SpringBootApplication
|
|
185
|
+
@ConfigurationPropertiesScan("com.example.config")
|
|
186
|
+
public class Application {}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Environment Variable Override
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# Override nested properties
|
|
193
|
+
APP_DATABASE_URL=jdbc:postgresql://prod/db
|
|
194
|
+
APP_SERVER_PORT=80
|
|
195
|
+
|
|
196
|
+
# Override list items
|
|
197
|
+
APP_ALLOWED_ORIGINS_0=http://example.com
|
|
198
|
+
APP_ALLOWED_ORIGINS_1=http://api.example.com
|
|
199
|
+
|
|
200
|
+
# Override map items
|
|
201
|
+
APP_SERVICES_USERSERVICE_URL=http://users:8080
|
|
202
|
+
```
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Spring Boot Web
|
|
3
|
+
description: REST controller patterns, request handling, validation, exception handling, and WebFlux.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [java, spring-boot, web, rest, api]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['**/*Controller.java', '**/*RestController.java']
|
|
8
|
+
keywords: [Controller, RestController, RequestMapping, GetMapping, PostMapping, PutMapping, DeleteMapping, ResponseBody, RequestBody, PathVariable, RequestParam]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Spring Boot Web Standards
|
|
12
|
+
|
|
13
|
+
## REST Controller
|
|
14
|
+
|
|
15
|
+
```java
|
|
16
|
+
@RestController
|
|
17
|
+
@RequestMapping("/api/v1/users")
|
|
18
|
+
@RequiredArgsConstructor
|
|
19
|
+
public class UserController {
|
|
20
|
+
|
|
21
|
+
private final UserService userService;
|
|
22
|
+
|
|
23
|
+
@GetMapping
|
|
24
|
+
public List<UserResponse> findAll(
|
|
25
|
+
@RequestParam(defaultValue = "0") int page,
|
|
26
|
+
@RequestParam(defaultValue = "20") int size) {
|
|
27
|
+
return userService.findAll(PageRequest.of(page, size))
|
|
28
|
+
.map(UserResponse::from)
|
|
29
|
+
.getContent();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@GetMapping("/{id}")
|
|
33
|
+
public UserResponse findById(@PathVariable Long id) {
|
|
34
|
+
return userService.findById(id)
|
|
35
|
+
.map(UserResponse::from)
|
|
36
|
+
.orElseThrow(() -> new ResourceNotFoundException("User", id));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@PostMapping
|
|
40
|
+
@ResponseStatus(HttpStatus.CREATED)
|
|
41
|
+
public UserResponse create(@Valid @RequestBody CreateUserRequest request) {
|
|
42
|
+
User user = userService.create(request);
|
|
43
|
+
return UserResponse.from(user);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@PutMapping("/{id}")
|
|
47
|
+
public UserResponse update(
|
|
48
|
+
@PathVariable Long id,
|
|
49
|
+
@Valid @RequestBody UpdateUserRequest request) {
|
|
50
|
+
User user = userService.update(id, request);
|
|
51
|
+
return UserResponse.from(user);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@DeleteMapping("/{id}")
|
|
55
|
+
@ResponseStatus(HttpStatus.NO_CONTENT)
|
|
56
|
+
public void delete(@PathVariable Long id) {
|
|
57
|
+
userService.delete(id);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Request DTOs with Validation
|
|
63
|
+
|
|
64
|
+
```java
|
|
65
|
+
public record CreateUserRequest(
|
|
66
|
+
@NotBlank @Size(min = 2, max = 100)
|
|
67
|
+
String name,
|
|
68
|
+
|
|
69
|
+
@NotBlank @Email
|
|
70
|
+
String email,
|
|
71
|
+
|
|
72
|
+
@NotBlank @Size(min = 8)
|
|
73
|
+
@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d).*$",
|
|
74
|
+
message = "must contain letters and numbers")
|
|
75
|
+
String password
|
|
76
|
+
) {}
|
|
77
|
+
|
|
78
|
+
public record UpdateUserRequest(
|
|
79
|
+
@Size(min = 2, max = 100)
|
|
80
|
+
String name,
|
|
81
|
+
|
|
82
|
+
@Email
|
|
83
|
+
String email
|
|
84
|
+
) {}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Response DTOs
|
|
88
|
+
|
|
89
|
+
```java
|
|
90
|
+
public record UserResponse(
|
|
91
|
+
Long id,
|
|
92
|
+
String name,
|
|
93
|
+
String email,
|
|
94
|
+
LocalDateTime createdAt
|
|
95
|
+
) {
|
|
96
|
+
public static UserResponse from(User user) {
|
|
97
|
+
return new UserResponse(
|
|
98
|
+
user.getId(),
|
|
99
|
+
user.getName(),
|
|
100
|
+
user.getEmail(),
|
|
101
|
+
user.getCreatedAt()
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Paginated response
|
|
107
|
+
public record PageResponse<T>(
|
|
108
|
+
List<T> content,
|
|
109
|
+
int page,
|
|
110
|
+
int size,
|
|
111
|
+
long totalElements,
|
|
112
|
+
int totalPages,
|
|
113
|
+
boolean last
|
|
114
|
+
) {
|
|
115
|
+
public static <T> PageResponse<T> from(Page<T> page) {
|
|
116
|
+
return new PageResponse<>(
|
|
117
|
+
page.getContent(),
|
|
118
|
+
page.getNumber(),
|
|
119
|
+
page.getSize(),
|
|
120
|
+
page.getTotalElements(),
|
|
121
|
+
page.getTotalPages(),
|
|
122
|
+
page.isLast()
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Exception Handling
|
|
129
|
+
|
|
130
|
+
```java
|
|
131
|
+
@RestControllerAdvice
|
|
132
|
+
public class GlobalExceptionHandler {
|
|
133
|
+
|
|
134
|
+
@ExceptionHandler(ResourceNotFoundException.class)
|
|
135
|
+
@ResponseStatus(HttpStatus.NOT_FOUND)
|
|
136
|
+
public ErrorResponse handleNotFound(ResourceNotFoundException ex) {
|
|
137
|
+
return new ErrorResponse("NOT_FOUND", ex.getMessage());
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@ExceptionHandler(MethodArgumentNotValidException.class)
|
|
141
|
+
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
|
142
|
+
public ErrorResponse handleValidation(MethodArgumentNotValidException ex) {
|
|
143
|
+
Map<String, String> errors = ex.getBindingResult()
|
|
144
|
+
.getFieldErrors()
|
|
145
|
+
.stream()
|
|
146
|
+
.collect(Collectors.toMap(
|
|
147
|
+
FieldError::getField,
|
|
148
|
+
FieldError::getDefaultMessage,
|
|
149
|
+
(a, b) -> a
|
|
150
|
+
));
|
|
151
|
+
return new ErrorResponse("VALIDATION_ERROR", "Validation failed", errors);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@ExceptionHandler(Exception.class)
|
|
155
|
+
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
|
156
|
+
public ErrorResponse handleGeneric(Exception ex) {
|
|
157
|
+
log.error("Unexpected error", ex);
|
|
158
|
+
return new ErrorResponse("INTERNAL_ERROR", "An unexpected error occurred");
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public record ErrorResponse(
|
|
163
|
+
String code,
|
|
164
|
+
String message,
|
|
165
|
+
Map<String, String> details
|
|
166
|
+
) {
|
|
167
|
+
public ErrorResponse(String code, String message) {
|
|
168
|
+
this(code, message, null);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Request Mapping Options
|
|
174
|
+
|
|
175
|
+
```java
|
|
176
|
+
// Path variables
|
|
177
|
+
@GetMapping("/{userId}/orders/{orderId}")
|
|
178
|
+
public Order getOrder(
|
|
179
|
+
@PathVariable Long userId,
|
|
180
|
+
@PathVariable Long orderId) {}
|
|
181
|
+
|
|
182
|
+
// Query parameters
|
|
183
|
+
@GetMapping("/search")
|
|
184
|
+
public List<User> search(
|
|
185
|
+
@RequestParam String query,
|
|
186
|
+
@RequestParam(required = false) String status,
|
|
187
|
+
@RequestParam(defaultValue = "name") String sortBy) {}
|
|
188
|
+
|
|
189
|
+
// Headers
|
|
190
|
+
@PostMapping
|
|
191
|
+
public void create(
|
|
192
|
+
@RequestHeader("X-Request-Id") String requestId,
|
|
193
|
+
@RequestHeader(value = "X-Tenant-Id", required = false) String tenantId) {}
|
|
194
|
+
|
|
195
|
+
// Request body
|
|
196
|
+
@PostMapping
|
|
197
|
+
public void create(@RequestBody @Valid CreateRequest request) {}
|
|
198
|
+
|
|
199
|
+
// Multipart file
|
|
200
|
+
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
|
201
|
+
public void upload(@RequestPart("file") MultipartFile file) {}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Best Practices
|
|
205
|
+
|
|
206
|
+
1. **Use records for DTOs** - immutable, concise
|
|
207
|
+
2. **Validate at controller level** with @Valid
|
|
208
|
+
3. **Return appropriate HTTP status codes**
|
|
209
|
+
4. **Use @RestControllerAdvice** for global exception handling
|
|
210
|
+
5. **Never expose entities** - always use DTOs
|
|
211
|
+
6. **Version your API** - /api/v1/resource
|
|
212
|
+
|
|
213
|
+
## References
|
|
214
|
+
|
|
215
|
+
- [REST Controller Patterns](references/rest-controller-patterns.md) - Advanced patterns
|
|
216
|
+
- [Validation Patterns](references/validation-patterns.md) - Custom validators, groups
|
|
217
|
+
- [Exception Handling](references/exception-handling.md) - Global handlers, ProblemDetail
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Spring Boot Web References
|
|
2
|
+
|
|
3
|
+
## References
|
|
4
|
+
|
|
5
|
+
- [**REST Controller Patterns**](rest-controller-patterns.md) - HATEOAS, async controllers, streaming
|
|
6
|
+
- [**Validation Patterns**](validation-patterns.md) - Custom validators, validation groups, cross-field
|
|
7
|
+
- [**Exception Handling**](exception-handling.md) - RFC 7807 ProblemDetail, error responses
|
|
8
|
+
|
|
9
|
+
## Quick Checks
|
|
10
|
+
|
|
11
|
+
- [ ] Use @RestController for REST APIs
|
|
12
|
+
- [ ] Validate input with @Valid on @RequestBody
|
|
13
|
+
- [ ] Use records for request/response DTOs
|
|
14
|
+
- [ ] Return proper HTTP status codes
|
|
15
|
+
- [ ] Global exception handling with @RestControllerAdvice
|
|
16
|
+
- [ ] Never expose JPA entities in API responses
|
|
17
|
+
- [ ] Version API endpoints (/api/v1/...)
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Spring Cloud
|
|
3
|
+
description: Service discovery, configuration, circuit breakers, load balancing, and API gateway.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [java, spring-boot, cloud, microservices]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['bootstrap.yml', 'application.yml', '**/*Discovery*.java', '**/*Client*.java']
|
|
8
|
+
keywords: [SpringCloud, DiscoveryClient, CircuitBreaker, Resilience4j, FeignClient, Gateway, LoadBalancer]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Spring Cloud Standards
|
|
12
|
+
|
|
13
|
+
## Service Discovery (Eureka)
|
|
14
|
+
|
|
15
|
+
```java
|
|
16
|
+
// Discovery Server
|
|
17
|
+
@SpringBootApplication
|
|
18
|
+
@EnableEurekaServer
|
|
19
|
+
public class DiscoveryServerApplication {}
|
|
20
|
+
|
|
21
|
+
// Client registration
|
|
22
|
+
@SpringBootApplication
|
|
23
|
+
@EnableDiscoveryClient
|
|
24
|
+
public class UserServiceApplication {}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
# Client configuration
|
|
29
|
+
spring:
|
|
30
|
+
application:
|
|
31
|
+
name: user-service
|
|
32
|
+
eureka:
|
|
33
|
+
client:
|
|
34
|
+
service-url:
|
|
35
|
+
defaultZone: http://localhost:8761/eureka
|
|
36
|
+
instance:
|
|
37
|
+
prefer-ip-address: true
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Feign Client
|
|
41
|
+
|
|
42
|
+
```java
|
|
43
|
+
@FeignClient(
|
|
44
|
+
name = "order-service",
|
|
45
|
+
fallbackFactory = OrderClientFallbackFactory.class
|
|
46
|
+
)
|
|
47
|
+
public interface OrderClient {
|
|
48
|
+
|
|
49
|
+
@GetMapping("/api/orders/{userId}")
|
|
50
|
+
List<Order> getOrdersByUser(@PathVariable Long userId);
|
|
51
|
+
|
|
52
|
+
@PostMapping("/api/orders")
|
|
53
|
+
Order createOrder(@RequestBody CreateOrderRequest request);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@Component
|
|
57
|
+
public class OrderClientFallbackFactory implements FallbackFactory<OrderClient> {
|
|
58
|
+
@Override
|
|
59
|
+
public OrderClient create(Throwable cause) {
|
|
60
|
+
return new OrderClient() {
|
|
61
|
+
@Override
|
|
62
|
+
public List<Order> getOrdersByUser(Long userId) {
|
|
63
|
+
log.warn("Fallback: returning empty orders", cause);
|
|
64
|
+
return List.of();
|
|
65
|
+
}
|
|
66
|
+
// ...
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Circuit Breaker (Resilience4j)
|
|
73
|
+
|
|
74
|
+
```java
|
|
75
|
+
@Service
|
|
76
|
+
public class PaymentService {
|
|
77
|
+
|
|
78
|
+
@CircuitBreaker(name = "payment", fallbackMethod = "fallback")
|
|
79
|
+
@Retry(name = "payment")
|
|
80
|
+
@TimeLimiter(name = "payment")
|
|
81
|
+
public CompletableFuture<PaymentResult> process(Payment payment) {
|
|
82
|
+
return CompletableFuture.supplyAsync(() -> paymentGateway.process(payment));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public CompletableFuture<PaymentResult> fallback(Payment payment, Throwable t) {
|
|
86
|
+
return CompletableFuture.completedFuture(PaymentResult.pending());
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```yaml
|
|
92
|
+
resilience4j:
|
|
93
|
+
circuitbreaker:
|
|
94
|
+
instances:
|
|
95
|
+
payment:
|
|
96
|
+
sliding-window-size: 10
|
|
97
|
+
failure-rate-threshold: 50
|
|
98
|
+
wait-duration-in-open-state: 30s
|
|
99
|
+
retry:
|
|
100
|
+
instances:
|
|
101
|
+
payment:
|
|
102
|
+
max-attempts: 3
|
|
103
|
+
wait-duration: 500ms
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## References
|
|
107
|
+
|
|
108
|
+
- [Service Discovery](references/service-discovery.md) - Eureka, Consul patterns
|
|
109
|
+
- [Circuit Breaker](references/circuit-breaker.md) - Resilience4j configuration
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Spring Cloud References
|
|
2
|
+
|
|
3
|
+
## References
|
|
4
|
+
|
|
5
|
+
- [**Service Discovery**](service-discovery.md) - Eureka, Consul, Kubernetes
|
|
6
|
+
- [**Circuit Breaker**](circuit-breaker.md) - Resilience4j patterns
|
|
7
|
+
|
|
8
|
+
## Quick Checks
|
|
9
|
+
|
|
10
|
+
- [ ] Use Resilience4j (not Hystrix - deprecated)
|
|
11
|
+
- [ ] Configure fallbacks for all external calls
|
|
12
|
+
- [ ] Set appropriate circuit breaker thresholds
|
|
13
|
+
- [ ] Use FeignClient for declarative HTTP clients
|