Developer Guide – POST Endpoint (v1.0)
The POST endpoint generates a complete Java project based on the submitted data. The system integrates domain definitions, business rules, and templates to build the project. The final output is a binary file (typically a ZIP archive) containing the generated code.
For further details, please refer to our repository documentation.
The following headers are required for configuring the LLM service integration (e.g., OpenAI or an alternative model):
meta-llama/llama-4-scout-17b-16e-instruct
).0.7
).1.0
).If credentials are provided in both headers and payload, header values take precedence.
entityDescriptor
"br.com.myapp"
"Produto"
"You are a Java software engineer specialized in Clean Code, SOLID, DDD, and Hexagonal Architecture. Generate only the requested code snippet without class definitions, imports, or extra comments. Generate only the method body."
"produtos"
name
(e.g., "id"
, "nome"
, etc.)type
(e.g., "java.lang.Long"
, "java.lang.String"
, etc.)primaryKey
, required
, generatedValue
, columnDefinition
.ruleName
(e.g., "CalcularDescontoProduto"
)description
(e.g., "calculate discount for products"
)ruleInput
(e.g., "br.com.myapp.domains.ProdutoDomain"
)ruleOutput
(e.g., "java.lang.Double"
or "java.lang.Void"
)llmGeneratedLogic
– Instruction for generating the rule’s code snippet.javaFunctionalInterface
and javaFuncionalIntefaceMethodName
– Define the functional interface and its method name.The payload must include three sets of templates:
name
and content
."templates/entity_test.ftl"
with its FreeMarker content."application.ftl"
and "entity.ftl"
). These must NOT contain "rule" in the name."rule_port.ftl"
. These must include "rule" in the name.{ "entityDescriptor": { "packageName": "br.com.myapp", "entityName": "Produto", "systemPrompt": "You are a Java software engineer specialized in Clean Code, SOLID, DDD, and Hexagonal Architecture. Generate only the requested code snippet without class definitions, imports, or extra comments. Generate only the method body.", "jpaDescriptor": { "tableName": "produtos", "attributes": [ {"name": "id", "type": "java.lang.Long", "primaryKey": true, "required": null, "maxLength": null, "generatedValue": true, "columnDefinition": null}, {"name": "nome", "type": "java.lang.String", "primaryKey": false, "required": true, "maxLength": null, "generatedValue": false, "columnDefinition": "VARCHAR(100)"}, {"name": "descricao", "type": "java.lang.String", "primaryKey": false, "required": true, "maxLength": null, "generatedValue": false, "columnDefinition": null}, {"name": "preco", "type": "java.lang.Double", "primaryKey": false, "required": true, "maxLength": null, "generatedValue": false, "columnDefinition": null} ] }, "rulesDescriptor": [ { "ruleName": "CalcularDescontoProduto", "description": "calculate discount for products", "ruleInput": "br.com.myapp.domains.ProdutoDomain", "ruleAdditionalInput": null, "ruleOutput": "java.lang.Double", "llmGeneratedLogic": "Implement discount logic for method applyDiscount: apply a 10% discount if price > 100. Return only the code snippet.", "javaFunctionalInterface": "java.util.function.Function", "javaFuncionalIntefaceMethodName": "apply" }, { "ruleName": "DespacharProduto", "description": "dispatch products for delivery", "ruleInput": "br.com.myapp.domains.ProdutoDomain", "ruleAdditionalInput": null, "ruleOutput": "java.lang.Void", "llmGeneratedLogic": "System.out.println(domain)", "javaFunctionalInterface": "java.util.function.Consumer", "javaFuncionalIntefaceMethodName": "accept" } ], "domainDescriptor": { "attributes": [ {"name": "id", "type": "java.lang.Long"}, {"name": "nome", "type": "java.lang.String"}, {"name": "descricao", "type": "java.lang.String"}, {"name": "preco", "type": "java.lang.Double"} ] }, "dtoDescriptor": { "attributes": [ {"name": "id", "type": "java.lang.Long"}, {"name": "nome", "type": "java.lang.String", "required": true, "maxLength": 100}, {"name": "descricao", "type": "java.lang.String", "required": true}, {"name": "preco", "type": "java.lang.Double"} ] } }, "templates": [ { "name": "templates/entity_test.ftl", "content": "<#import \"testValueModule.ftl\" as testValues>\n\npackage br.com.myapp.entities;\n\nimport org.junit.jupiter.api.Test;\nimport static org.junit.jupiter.api.Assertions.*;\n\nclass ProdutoEntityTest {\n @Test\n void testProdutoEntityGettersAndSetters() {\n final ProdutoEntity entity = new ProdutoEntity();\n <#list jpaDescriptor.attributes as attribute>\n final ${attribute.type} ${attribute.name}Value = <@testValues.generateTestValue attribute.type />;\n entity.set${attribute.name?cap_first}(${attribute.name}Value);\n assertEquals(${attribute.name}Value, entity.get${attribute.name?cap_first}());\n #list>\n }\n}\n" }, { "name": "templates/dto.ftl", "content": "package br.com.myapp.dtos;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport com.fasterxml.jackson.databind.annotation.JsonDeserialize;\n\nimport lombok.AccessLevel;\nimport lombok.Builder;\nimport lombok.Value;\n\nimport jakarta.validation.constraints.*;\n\n@Value\n@Builder(access = AccessLevel.PUBLIC, toBuilder = true)\n@JsonDeserialize(builder = ProdutoDTO.ProdutoDTOBuilder.class)\npublic class ProdutoDTO {\n <#list dtoDescriptor.attributes as attribute>\n <#if attribute.required>\n @NotNull(message = \"${attribute.name} is required\")\n #if>\n <#if attribute.maxLength>\n @Size(max = ${attribute.maxLength}, message = \"${attribute.name} cannot exceed ${attribute.maxLength} characters\")\n #if>\n @JsonProperty\n ${attribute.type} ${attribute.name};\n #list>\n}\n" } ], "standardTemplates": [ { "templateName": "application.ftl", "outputPathPattern": "generated/src/main/java/br/com/myapp/ProdutoApplication.java", "dataModelKey": "domain", "additionalData": {"author": "Alexandre M S Lima", "date": "2024-10-26"} }, { "templateName": "entity.ftl", "outputPathPattern": "generated/src/main/java/br/com/myapp/entities/ProdutoEntity.java", "dataModelKey": "jpa", "additionalData": {"author": "Alexandre M S Lima", "date": "2024-10-26"} } ], "rulesTemplates": [ { "templateName": "rule_port.ftl", "outputPathPattern": "generated/src/main/java/br/com/myapp/rules/CalcularDescontoProdutoRulePort.java", "dataModelKey": "jpa", "additionalData": null } ] }
Note: This example includes inline explanations. In practice, remove any comments from the JSON.
The JSON payload is converted into a Genhex4jDTO
object and validated using annotations (e.g., @NotNull
, @NotEmpty
).
Headers are processed by the headersToLLmCredencial
method to create a LLMCredencials
object. Header credentials override payload values if both are provided.
The three sets of templates (templates
, standardTemplates
, and rulesTemplates
) are passed to the generateCode
method along with the entityDescriptor
. The template engine (e.g., FreeMarker) processes each template by replacing variables (e.g., "br.com.myapp" and "Produto") with the provided values.
Required Templates: At minimum, you must provide:
templates
: Additional custom templates.standardTemplates
: At least "application.ftl" and "entity.ftl" (must not include "rule" in the name).rulesTemplates
: At least one business rule template (e.g., "rule_port.ftl"; must include "rule" in the name).Omitting any required template set may result in incomplete project generation.
Processed templates are assembled into a structured project, then compressed into a ZIP archive. The generateCode
method returns a Pair<String, byte[]>
where the byte[]
represents the ZIP file.
The byte array is wrapped in a ResponseEntity<byte[]>
via the createResponse
method, with Content-Type: application/octet-stream
for download.
application/octet-stream
Error Handling: Common error responses include:
400 Bad Request
– Invalid payload or missing required fields.500 Internal Server Error
– Processing errors during code generation.Payload size should not exceed 1MB. Average processing time is ~10 seconds, with a maximum of 30 seconds.