Hello Simon,
thx for answering!
sounds good, i think i will go this way.
Java-Records are really nice / concise and also have toString, equals,
hashCode which can also be helpful.
I see two ways where the projection can be build with:
- a) ... on the Jooq-Records (Jooq-Record Classes generated by Codegen)
- b) ... directly on the Jooq DSL
i think you have meant b) in your example. And i will also go that way i
think,
Sometimes it can also be good to go with a) because then at least
Bulk/Batch Inserts and similar performance-optimizations can be done in an
AbstractDAO for the inserts.
But b) is simpler (has less code-parts / more concise)
Here an example for a) and for a REST Create Endpoint.
Each endpoint would have individual DTOs for Reqest/Response, as defined by
CQRS.
---
*ProductControllerV1*
public CreateProductResponseV1 create(CreateProductRequestV1
createProductRequest) throws ValidationException {
return productManager.create(new RequestContext(1, 1),
createProductRequest);
}
---
*ProductManagerV1*
public CreateProductResponseV1 create(RequestContext requestContext,
final CreateProductRequestV1 createProductRequest) throws
ValidationException {
return database1.dsl(requestContext).transactionResult(tsx -> {
ProductDAOV1 productDAOV1 = new ProductDAOV1(tsx.dsl());
this.validate(createProductRequest);
// request-dto to jooq-record projection
ProductRecord insert = new ProductRecord();
insert.setClientId(createProductRequest.clientId());
insert.setPrice(createProductRequest.price());
insert.setTypeId(createProductRequest.typeId());
insert.setDeleted(false);
productDAOV1.insert(insert);
ProductRecord result
= productDAOV1.fetch(insert.getProductId());
// jooq-record to response-dto projection
return new CreateProductResponseV1(
result.getProductId(),
result.getClientId(),
result.getPrice(),
result.getTypeId(),
result.getCreatedAt(),
result.getUpdatedAt(),
result.getDeleted(),
result.getCreatorId()
);
});
}
---
*CreateProductRequestV1*
public record CreateProductRequestV1(
@NotNull Integer clientId,
@NotNull BigDecimal price,
@NotNull @Size(max = 255) String typeId
) {
}
---
*CreateProductResponseV1*
public record CreateProductResponse(
@NotNull Long productId,
@NotNull Integer clientId,
@NotNull BigDecimal price,
@NotNull @Size(max = 255) String typeId,
@NotNull LocalDateTime createdAt,
@NotNull LocalDateTime updatedAt,
@NotNull Boolean deleted,
@NotNull Integer creatorId
) {
}
---
additional, if the DAO is used for the projection (like you suggested) the
DAO insert-method could look like this,
for example:
*ProductDAOV1*
public class ProductDAOV1 extends AbstractDAO<ProductRecord, Long> {
...
int insertProduct(CreateProductRequestV1 createProductRequest) {
return dsl()
.insertInto(PRODUCT)
.set(PRODUCT.CLIENTID, createProductRequest.clientId())
.set(PRODUCT.PRICE, createProductRequest.price())
.set(PRODUCT.TYPEID, createProductRequest.typeId())
.set(PRODUCT.DELETED, false)
.execute();
}
}
[email protected] schrieb am Sonntag, 13. Oktober 2024 um 10:14:26 UTC:
> Hi Bernd,
>
> If you need to support mulitple versions of your API and this only
> involves the projection part of your query, then you must create a
> projection per DTO (preferably as Java Record).
> That could be abstracted in versioned repositories (DAOs).
>
> There would also be a more generic approach to derive the projection
> directly from the constructor of the Java Record. But this would require
> reflection and is not compile-time checked.
>
> That’s how I would do it.
>
> Kind regards,
> Simon
>
>
>
> On 13 Oct 2024, at 10:16, 'Bernd Huber' via jOOQ User Group <
> [email protected]> wrote:
>
> Hello guys,
>
> i really loved the following video by Victor Rentea about REST API Design
> Pitfalls.
> - https://www.youtube.com/watch?v=CNlLWCvazcQ
>
> in my company we also need to build a Versioned REST-Api, which some
> specific Clients can use in a secure way.
>
> Can someone recommend me an Article or Best-Practice how to integrate Jooq
> in such a scenario ?
>
> I can think of something like ...
> - i manually create versioned DTOs (ProductDTOV1, ProductDTOV2, ...) as
> simple Pojos.
> - i manually write Insert / Update / Delete Methods in my DAOs where i
> need to boilerplate down all the fields i want to consider for each
> specific case.
> - i write a Repository where i Select data and also concretely
> (boilerplate) map each field i select into the versioned DTO.
> - the Jooq-Codegen-Classes are only used in internal Jobs where REST is
> not involved, as they are just an unnecessary middle-man for the REST
> use-cases.
>
> I know that Jooq does support everything i want to do with it, but I often
> tend to overabstract, and i hope to find a simple way (even if its
> boilerplate) to write REST-Apis with jooq, that do not involve
> overabstracted solutions where they are counterproductive.
>
> I guess the outline i have shown here should work.
>
> best regards,
>
> Bernd Huber
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "jOOQ User Group" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/jooq-user/ac30997e-16c1-4b74-adb7-03ebf8487255n%40googlegroups.com
>
> <https://groups.google.com/d/msgid/jooq-user/ac30997e-16c1-4b74-adb7-03ebf8487255n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
>
>
--
You received this message because you are subscribed to the Google Groups "jOOQ
User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/jooq-user/9eb58e6a-0f04-48a7-89d4-0145d913ef4bn%40googlegroups.com.