Skills Plugins MCP Prompt Model 博客 我的中心

quarkus-patterns

Patrones de arquitectura Quarkus 3.x LTS con Camel para mensajería, diseño de API RESTful, servicios CDI, acceso a datos con Panache y procesamiento asíncrono.

DeepseekModel キュレーション済みスキル 品質 優秀 · 90 v1.0.0

取得

https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-docs-es-skills-quarkus-patterns-skill-md&format=skill
ダウンロード .skill 標準形式。system_prompt と model_config を収録し、任意の Agent で利用可能
.skill ファイルの system_prompt フィールドの実際の内容。
name quarkus-patterns description Patrones de arquitectura Quarkus 3.x LTS con Camel para mensajería, diseño de API RESTful, servicios CDI, acceso a datos con Panache y procesamiento asíncrono. origin ECC Patrones de Desarrollo Quarkus Patrones de arquitectura y API de Quarkus 3.x para servicios cloud-native y orientados a eventos con Apache Camel. Cuándo Activar Construir APIs REST con JAX-RS o RESTEasy Reactive Estructurar capas resource → service → repository Implementar patrones orientados a eventos con Apache Camel y RabbitMQ Configurar Hibernate Panache, caché o streams reactivos Agregar validación, mapeo de excepciones o paginación Configurar perfiles para entornos dev/staging/producción (configuración YAML) Logging personalizado con LogContext y Logback/Logstash encoder Trabajar con CompletableFuture para operaciones asíncronas Implementar procesamiento condicional de flujos Trabajar con compilación nativa GraalVM Capa de Servicio con Múltiples Dependencias @Slf4j @ApplicationScoped @RequiredArgsConstructor public class OrderProcessingService { private final OrderValidator orderValidator; private final EventService eventService; private final OrderRepository orderRepository; private final FulfillmentPublisher fulfillmentPublisher; private final AuditPublisher auditPublisher; @Transactional public OrderReceipt process (CreateOrderCommand command) { ValidationResult validation = orderValidator.validate(command); if (!validation.valid()) { eventService.createErrorEvent(command, "ORDER_REJECTED" , validation.message()); throw new WebApplicationException (validation.message(), Response.Status.BAD_REQUEST); } Order order = Order.from(command); orderRepository.persist(order); OrderReceipt receipt = OrderReceipt.from(order); fulfillmentPublisher.publishAsync(receipt); auditPublisher.publish( "ORDER_ACCEPTED" , receipt); eventService.createSuccessEvent(receipt, "ORDER_ACCEPTED" ); log.info( "Orden procesada {}" , order.id); return receipt; } } Patrones Clave: @RequiredArgsConstructor para inyección por constructor mediante Lombok @Slf4j para logging con Logback @Transactional en métodos de servicio que escriben a través de Panache o repositorios Validar entrada antes de persistencia o publicación de mensajes Seguimiento de eventos para escenarios de éxito/error Publicación asíncrona de mensajes Camel Patrón de Contexto de Logging Personalizado (Logback) @ApplicationScoped public class ProcessingService { public void processDocument (Document doc) { LogContext logContext = CustomLog.getCurrentContext(); try ( SafeAutoCloseable ignored = CustomLog.startScope(logContext)) { logContext.put( "documentId" , doc.getId().toString()); logContext.put( "documentType" , doc.getType()); logContext.put( "userId" , SecurityContext.getUserId()); log.info( "Iniciando procesamiento de documento" ); processInternal(doc); log.info( "Procesamiento de documento completado" ); } catch (Exception e) { log.error( "Error en el procesamiento de documento" , e); throw e; } } } Configuración de Logback (logback.xml): < configuration > < appender name = "CONSOLE" class = "ch.qos.logback.core.ConsoleAppender" > < encoder class = "net.logstash.logback.encoder.LogstashEncoder" > < includeContext > true </ includeContext > < includeMdc > true </ includeMdc > </ encoder > </ appender > < logger name = "com.example" level = "INFO" /> < root level = "WARN" > < appender-ref ref = "CONSOLE" /> </ root > </ configuration > Patrón de Servicio de Eventos @Slf4j @ApplicationScoped @RequiredArgsConstructor public class EventService { private final EventRepository eventRepository; private final ObjectMapper objectMapper; public void createSuccessEvent (Object payload, String eventType) { Objects.requireNonNull(payload, "El payload no puede ser null" ); Event event = new Event (); event.setType(eventType); event.setStatus(EventStatus.SUCCESS); event.setPayload(serializePayload(payload)); event.setTimestamp(Instant.now()); eventRepository.persist(event); log.info( "Evento de éxito creado: {}" , eventType); } public void createErrorEvent (Object payload, String eventType, String errorMessage) { Objects.requireNonNull(payload, "El payload no puede ser null" ); if (errorMessage == null || errorMessage.isBlank()) { throw new IllegalArgumentException ( "El mensaje de error no puede estar en blanco" ); } Event event = new Event (); event.setType(eventType); event.setStatus(EventStatus.ERROR); event.setErrorMessage(errorMessage); event.setPayload(serializePayload(payload)); event.setTimestamp(Instant.now()); eventRepository.persist(event); log.error( "Evento de error creado: {} - {}" , eventType, errorMessage); } private String serializePayload (Object payload) { try { return objectMapper.writeValueAsString(payload); } catch (JsonProcessingException e) { throw new IllegalStateException ( "Error al serializar el payload del evento" , e); } } } Publicación de Mensajes Camel (RabbitMQ) @Slf4j @ApplicationScoped @RequiredArgsConstructor public class BusinessRulesPublisher { private final ProducerTemplate producerTemplate; public void publishSync (BusinessRulesPayload payload) { producerTemplate.sendBody( "direct:business-rules-publisher" , payload ); } } Configuración de Ruta Camel: @ApplicationScoped public class BusinessRulesRoute extends RouteBuilder { @ConfigProperty(name = "camel.rabbitmq.queue.business-rules") String businessRulesQueue; @ConfigProperty(name = "rabbitmq.host") String rabbitHost; @ConfigProperty(name = "rabbitmq.port") Integer rabbitPort; @Override public void configure () { from( "direct:business-rules-publisher" ) .routeId( "business-rules-publisher" ) .log( "Publicando mensaje en RabbitMQ: ${body}" ) .marshal().json(JsonLibrary.Jackson) .toF( "spring-rabbitmq:%s?hostname=%s&portNumber=%d" , businessRulesQueue, rabbitHost, rabbitPort); } } Rutas Camel Direct (En Memoria) @ApplicationScoped public class DocumentProcessingRoute extends RouteBuilder { @Override public void configure () { onException(ValidationException.class) .handled( true ) .to( "direct:validation-error-handler" ) .log( "Error de validación: ${exception.message}" ); from( "direct:process-document" ) .routeId( "document-processing" ) .log( "Procesando documento: ${header.documentId}" ) .bean(DocumentValidator.class, "validate" ) .bean(DocumentTransformer.class, "transform" ) .choice() . when (header( "documentType" ).isEqualTo( "INVOICE" )) .to( "direct:process-invoice" ) . when (header( "documentType" ).isEqualTo( "CREDIT_NOTE" )) .to( "direct:process-credit-note" ) .otherwise() .to( "direct:process-generic" ) .end(); } } Procesamiento de Archivos Camel @ApplicationScoped public class FileMonitoringRoute extends RouteBuilder { @ConfigProperty(name = "file.input.directory") String inputDirectory; @ConfigProperty(name = "file.processed.directory") String processedDirectory; @ConfigProperty(name = "file.error.directory") String errorDirectory; @Override public void configure () { from( "file:" + inputDirectory + "?move=" + processedDirectory + "&moveFailed=" + errorDirectory + "&delay=5000" ) .routeId( "file-monitor" ) .log( "Procesando archivo: ${header.CamelFileName}" ) .to( "direct:process-file" ); } } Estructura de API REST @Path("/api/documents") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @RequiredArgsConstructor public class DocumentResource { private final DocumentService documentService; @GET public Response list ( @QueryParam("page") @DefaultValue("0") int page, @QueryParam("size") @DefaultValue("20") int size) { List<Document> documents = documentService.list(page, size); return Response.ok(documents).build(); } @POST public Response create ( @Valid CreateDocumentRequest request, @Context UriInfo uriInfo) { Document document = documentService.create(request); URI location = uriInfo.getAbsolutePathBuilder() .path(String.valueOf(document.id)) .build(); return Response.created(location).entity(DocumentResponse.from(document)).build(); } @GET @Path("/{id}") public Response getById ( @PathParam("id") Long id) { return documentService.findById(id) .map(DocumentResponse::from) .map(Response::ok) .orElse(Response.status(Response.Status.NOT_FOUND)) .build(); } } Patrón de Repositorio (Panache Repository) @ApplicationScoped public class DocumentRepository implements PanacheRepository <Document> { public List<Document> findByStatus (DocumentStatus status, int page, int size) { return find( "status = ?1 order by createdAt desc" , status) .page(page, size) .list(); } public Optional<Document> findByReferenceNumber (String referenceNumber) { return find( "referenceNumber" , referenceNumber).firstResultOptional(); } } Capa de Servicio con Transacciones @ApplicationScoped @RequiredArgsConstructor public class DocumentService { private final DocumentRepository repo; private final EventService eventService; @Transactional public Document create (CreateDocumentRequest request) { Document document = new Document (); document.setReferenceNumber(request.referenceNumber()); document.setDescription(request.description()); document.setStatus(DocumentStatus.PENDING); document.setCreatedAt(Instant.now()); repo.persist(document); eventService.createSuccessEvent(document, "DOCUMENT_CREATED" ); return document; } } DTOs y Validación public record CreateDocumentRequest ( @NotBlank @Size(max = 200) String referenceNumber, @NotBlank @Size(max = 2000) String description, @NotNull @FutureOrPresent Instant validUntil, @NotEmpty List< @NotBlank String> categories) {} public record DocumentResponse (Long id, String referenceNumber, DocumentStatus status) { public static DocumentResponse from (Document document) { return new DocumentResponse (document.getId(), document.getReferenceNumber(), document.getStatus()); } } Mapeo de Excepciones @Provider public class ValidationExceptionMapper implements ExceptionMapper <ConstraintViolationException> { @Override public Response toResponse (ConstraintViolationException exception) { String message = exception.getConstraintViolations().stream() .map(cv -> cv.getPropertyPath() + ": " + cv.getMessage()) .collect(Collectors.joining( ", " )); return Response.status(Response.Status.BAD_REQUEST) .entity(Map.of( "error" , "validation_error" , "message" , message)) .build(); } } Operaciones Asíncronas con CompletableFuture @Slf4j @ApplicationScoped @RequiredArgsConstructor public class FileStorageService { private final S3Client s3Client; private final ExecutorService executorService; public CompletableFuture<StoredDocumentInfo> uploadOriginalFile ( InputStream inputStream, long size, LogContext logContext, InvoiceFormat format) { return CompletableFuture.supplyAsync(() -> { try ( SafeAutoCloseable ignored = CustomLog.startScope(logContext)) { String path = generateStoragePath(format); PutObjectRequest request = PutObjectRequest.builder() .bucket(bucketName) .key(path) .contentLength(size) .build(); s3Client.putObject(request, RequestBody.fromInputStream(inputStream, size)); return new StoredDocumentInfo (path, size, Instant.now()); } catch (Exception e) { log.error( "Error al subir archivo a S3" , e); throw new StorageException ( "Subida fallida" , e); } }, executorService); } } Caché @ApplicationScoped @RequiredArgsConstructor public class DocumentCacheService { private final DocumentRepository repo; @CacheResult(cacheName = "document-cache") public Optional<Document> getById ( @CacheKey Long id) { return repo.findByIdOptional(id); } @CacheInvalidate(cacheName = "document-cache") public void evict ( @CacheKey Long id) {} } Configuración como YAML # application.yml "%dev" : quarkus: datasource: jdbc: url: jdbc:postgresql://localhost:5432/dev_db username: dev_user password: ${DB_PASSWORD} "%test" : quarkus: datasource: jdbc: url: jdbc:h2:mem:test hibernate-orm: database: generation: drop-and-create "%prod" : quarkus: datasource: jdbc: url: ${DATABASE_URL} username: ${DB_USER} password: ${DB_PASSWORD} Health Checks @Readiness @ApplicationScoped @RequiredArgsConstructor public class DatabaseHealthCheck implements HealthCheck { private final AgroalDataSource dataSource; @Override public HealthCheckResponse call () { try ( Connection conn = dataSource.getConnection()) { boolean valid = conn.isValid( 2 ); return HealthCheckResponse.named( "Database connection" ) .status(valid) .build(); } catch (SQLException e) { return HealthCheckResponse.down( "Database connection" ); } } } Dependencias (Maven) < properties >
このスキルを起動するキーワード。クリックでコピーできます。

このスキルにはトリガーワードがありません。

ダウンロードした .skill に含まれるフィールド。
フィールド 説明
formatフォーマット識別子(skill/v1)
skill_idスキル固有 ID
nameスキル名
versionバージョン
description説明
categoryカテゴリ(配列)
trigger_wordsトリガーワード
tagsタグ
sourceソース
source_urlソース URL(本ページ)
exported_atエクスポート日時(ダウンロード毎)
system_promptシステムプロンプト本文
model_configモデル設定:provider / model / temperature / max_tokens / top_p
examplesサンプル
install_guide各プラットフォームの導入説明(Coze / Dify / Claude / カスタム)
同じスキルを各プラットフォーム形式で出力できます。
.skill 標準形式。system_prompt と model_config を収録し、任意の Agent で利用可能 ダウンロード
.skillpro 拡張形式。scripts / tools / dependencies / hooks を含む ダウンロード
.json 純粋な JSON 出力。system_prompt とモデル設定のみ ダウンロード
Coze frontmatter 付き Markdown。Coze へのインポート用 ダウンロード
Dify Dify DSL。アプリ作成後にそのままインポート ダウンロード

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。