also a complete projection in the DAO could look like this,
and if Get-Queries are done it would also be necessary to make projections 
in MULTISET with help of convertFrom (nested convertFrom for table-joins) 

*ProductDAOV1*

    public CreateProductResponseV1 create(CreateProductRequestV1 
createProductRequest) {

        // project request to jooq-query.
        Long productId = dsl()
            .insertInto(PRODUCT)
            .set(PRODUCT.CLIENTID, createProductRequest.clientId())
            .set(PRODUCT.PRICE, createProductRequest.price())
            .set(PRODUCT.TYPEID, createProductRequest.typeId())
            .set(PRODUCT.DELETED, false)
            .returning(PRODUCT.PRODUCTID)
            .fetchOne(PRODUCT.PRODUCTID);

        // get db-content for id, and project to response...
        Record1<CreateProductResponse> result = dsl()
            .select(
                row(
                    PRODUCT.PRODUCTID,
                    PRODUCT.CLIENTID,
                    PRODUCT.PRICE,
                    PRODUCT.TYPEID,
                    PRODUCT.CREATEDAT,
                    PRODUCT.UPDATEDAT,
                    PRODUCT.DELETED,
                    PRODUCT.CREATORID
                ).convertFrom(x -> x.into(CreateProductResponseV1.class))
            )
            .from(PRODUCT)
            .where(PRODUCT.PRODUCTID.eq(productId))
            .fetchOne();

        if (result != null) {
            return result.value1();
        } else {
            throw new MappingException("internal error");
        }
    }



Bernd Huber schrieb am Sonntag, 13. Oktober 2024 um 12:50:36 UTC:

> 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/d70cbf51-4536-4e17-85cf-daa25950cb93n%40googlegroups.com.

Reply via email to