Skip to content

Commit

Permalink
Feature/update example webapp (#15)
Browse files Browse the repository at this point in the history
* added README
* Cleanup and restore example
* Added examples to project build
  • Loading branch information
p3t authored Jun 25, 2024
1 parent c8be0f3 commit 87007bb
Show file tree
Hide file tree
Showing 32 changed files with 364 additions and 142 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
HELP.md

.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
Expand Down Expand Up @@ -36,3 +36,5 @@ out/
### VS Code ###
.vscode/
/lib/

**/generated_tests/*
67 changes: 2 additions & 65 deletions cursorpaging-examples/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,65 +1,2 @@
plugins {
java
id("org.springframework.boot")
id("io.vigier.java-library-conventions")
}

group = "io.vigier.cursorpaging"
version = "0-SNAPSHOT"

dependencies {
val mapstructVersion: String by extra("1.5.5.Final")

implementation(project(":cursorpaging-jpa"))
implementation(project(":cursorpaging-jpa-api"))

implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.hateoas:spring-hateoas")
implementation("org.springframework.retry:spring-retry")
implementation("org.springframework:spring-aspects")
implementation("org.apache.commons:commons-lang3")
// compileOnly("javax.xml.bind:jaxb-api")

implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0")
implementation("org.mapstruct:mapstruct:${mapstructVersion}")

annotationProcessor("org.mapstruct:mapstruct-processor:${mapstructVersion}")
annotationProcessor("org.hibernate:hibernate-jpamodelgen:6.5.0.Final")

// implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
// implementation("org.springframework.boot:spring-boot-starter-data-mongodb-reactive")
// implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
// implementation("org.liquibase:liquibase-core")


runtimeOnly("org.postgresql:postgresql")
// runtimeOnly("org.postgresql:r2dbc-postgresql")

// annotationProcessor("org.hibernate:hibernate-jpamodelgen")
// annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")

developmentOnly("org.springframework.boot:spring-boot-devtools")
developmentOnly("org.springframework.boot:spring-boot-docker-compose")

testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.boot:spring-boot-testcontainers")
testImplementation("org.testcontainers:junit-jupiter")
testImplementation("org.testcontainers:postgresql")
// testImplementation("io.projectreactor:reactor-test")
// testImplementation("org.testcontainers:mongodb")
// testImplementation("org.testcontainers:r2dbc")
}

tasks {
javadoc {
options {
(this as CoreJavadocOptions).addStringOption("Xdoclint:none", "-quiet")
}
}
test {
useJUnitPlatform()
}

}
group = "io.vigier.cursorpaging.examples"
version = findProperty("version") ?: System.getenv("BUILD_VERSION") ?: "0-SNAPSHOT"

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
HELP.md
target/
build/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
!**/src/main/**/build/
!**/src/test/**/build/
.mvn/settings.xml
.mvn/maven.config

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@
This should be a half-way realistic application implementation used to demonstrate cursor-based pagination. The
application is a simple Spring Boot web application that exposes a REST API to manage a list of data-records.

## Build-notice (gradle vs. maven)!

The project build with gradle is integrated in the cursorpaging overall continuous build - and should work all the time.
The maven build is using the latest released version of the libraries and is only updated in case of an new release.
Therefor it is possible, that it will fail in case new features are used which are not yet released!

## Required infrastructure

For running the application, you need a PostgreSQL ( s. the [compose.yml](../compose.yml) ) and a Java 17 runtime.
For running the application, you need a PostgreSQL ( s. the [docker-compose.yaml](docker-compose.yaml) ) and a Java 17 runtime.

## Components

Expand Down Expand Up @@ -75,20 +81,20 @@ problematic. Here some tries:
public CollectionModel<DtoDataRecord> getDataRecords(

// All of this variants will result in a "no matching editors or conversion strategy found" error
@Parameter() @RequestParam( required = false ) final List<AttributeOrder> order
@Parameter( style = ParameterStyle.DEEPOBJECT ) @RequestParam( required = false ) final List<AttributeOrder> order
@Parameter( style = ParameterStyle.DEEPOBJECT ) @RequestParam( required = false ) final AttributeOrder[] order
@Parameter( style = ParameterStyle.FORM ) @RequestParam( required = false ) final AttributeOrder order
@Parameter() @RequestParam( required = false ) final List<AttributeOrder> order1,
@Parameter( style = ParameterStyle.DEEPOBJECT ) @RequestParam( required = false ) final List<AttributeOrder> order2,
@Parameter( style = ParameterStyle.DEEPOBJECT ) @RequestParam( required = false ) final AttributeOrder[] order3,
@Parameter( style = ParameterStyle.FORM ) @RequestParam( required = false ) final AttributeOrder order4,

// order = null, just not mapped
@Parameter( style = ParameterStyle.DEEPOBJECT ) @RequestParam( required = false ) final AttributeOrder order
@Parameter( style = ParameterStyle.DEEPOBJECT ) @RequestParam( required = false ) final AttributeOrder order5,

// works but the field must be required, to be shown in swagger
@Parameter( description = "Define the order of the records", example = """
{
"NAME": "DESC",
"ID": "ASC"
}""" ) @RequestParam( defaultValue = "{}" ) final Map<DataRecordAttribute, Order> orderBy
}""" ) @RequestParam( defaultValue = "{}" ) final Map<DataRecordAttribute, Order> orderBy,

// still there is the glitch, that when adding multiple parameters, all of them contain all request parameter.
// We can use this to have a good representation in Swagger, but we need to parse the request parameters by hand
Expand Down Expand Up @@ -116,6 +122,7 @@ Other considered alternatives:
- Use simple parameters, and name them as the model
properties: `@RequestParam( required = false ) final Order orderByName, @RequestParam( required = false ) final Order orderByCreatedAt`
- Encode all in the attribute enum: "ORDER_BY_NAME_ASC", "ORDER_BY_CREATED_AT_DESC, etc."
- Just use a string and decode the contained json in the controller method.

As there is a significant difference between creating a cursor for the first page and requesting the data for all
subsequent page requests, personally I liked the POST approach most.
68 changes: 68 additions & 0 deletions cursorpaging-examples/webapp-with-maven/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Gradle build to include the example in the project build
// While the maven pom.xml es executed separately

plugins {
java
id("org.springframework.boot")
id("io.vigier.java-library-conventions")
}

group = "io.vigier.cursorpaging.examples.webapp"
version = findProperty("version") ?: System.getenv("BUILD_VERSION") ?: "0-SNAPSHOT"

dependencies {
val mapstructVersion: String by extra("1.5.5.Final")

implementation(project(":cursorpaging-jpa"))
implementation(project(":cursorpaging-jpa-api"))

implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.hateoas:spring-hateoas")
implementation("org.springframework.retry:spring-retry")
implementation("org.springframework:spring-aspects")
implementation("org.apache.commons:commons-lang3")
// compileOnly("javax.xml.bind:jaxb-api")

implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0")
implementation("org.mapstruct:mapstruct:${mapstructVersion}")

annotationProcessor("org.mapstruct:mapstruct-processor:${mapstructVersion}")
annotationProcessor("org.hibernate:hibernate-jpamodelgen:6.5.0.Final")

// implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
// implementation("org.springframework.boot:spring-boot-starter-data-mongodb-reactive")
// implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
// implementation("org.liquibase:liquibase-core")


runtimeOnly("org.postgresql:postgresql")
// runtimeOnly("org.postgresql:r2dbc-postgresql")

// annotationProcessor("org.hibernate:hibernate-jpamodelgen")
// annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")

developmentOnly("org.springframework.boot:spring-boot-devtools")
developmentOnly("org.springframework.boot:spring-boot-docker-compose")

testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.boot:spring-boot-testcontainers")
testImplementation("org.testcontainers:junit-jupiter")
testImplementation("org.testcontainers:postgresql")
// testImplementation("io.projectreactor:reactor-test")
// testImplementation("org.testcontainers:mongodb")
// testImplementation("org.testcontainers:r2dbc")
}

tasks {
javadoc {
options {
(this as CoreJavadocOptions).addStringOption("Xdoclint:none", "-quiet")
}
}
test {
useJUnitPlatform()
}

}
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,44 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<version>3.3.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>io.vigier</groupId>
<artifactId>cursorpaging-example-maven</artifactId>
<artifactId>cursorpaging-example-webapp-with-maven</artifactId>
<version>0-SNAPSHOT</version>

<name>cursorpaging :: example :: maven</name>
<name>cursorpaging :: example :: webapp-maven</name>
<description>An maven build setup, using a released version of the cursorpaging libraries.</description>

<properties>
<java.version>17</java.version>
<mapstruct.version>1.5.5.Final</mapstruct.version>
<lombok.version>1.18.32</lombok.version>
<cursorpage.version>0.0.1-RC4</cursorpage.version>
<cursorpage.version>0.8.0-RC1</cursorpage.version>
<testcontainers.version>1.19.8</testcontainers.version>
</properties>

<repositories>
<repository>
<id>p3t-github-packages</id>
<url>https://maven.pkg.github.com/p3t/spring-cursorpaging</url>
</repository>
</repositories>
<profiles>
<profile>
<id>githubPackages</id>
<activation>
<property>
<name>githubPackages</name>
</property>
</activation>
<repositories>
<repository>
<id>p3t-github-packages</id>
<url>https://maven.pkg.github.com/p3t/spring-cursorpaging</url>
</repository>
</repositories>
<properties>
<cursorpage.version>0.8.0-RC1</cursorpage.version>
</properties>
</profile>
</profiles>

<dependencies>
<dependency>
Expand Down Expand Up @@ -90,8 +104,35 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<!-- If you are using Spring Boot 3.1.0+ then you don't need to configure testcontainers-bom -->
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
<version>${testcontainers.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.vigier.cursorpaging.example.webapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ExampleWebApplication {

public static void main( final String[] args ) {
SpringApplication.run( ExampleWebApplication.class, args );
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.vigier.cursorpaging.testapp.api.controller;
package io.vigier.cursorpaging.example.webapp.api.controller;

import jakarta.validation.ValidationException;
import org.springframework.http.ResponseEntity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
package io.vigier.cursorpaging.testapp.api.controller;
package io.vigier.cursorpaging.example.webapp.api.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterStyle;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.vigier.cursorpaging.example.webapp.api.model.DataRecordAttribute;
import io.vigier.cursorpaging.example.webapp.api.model.DtoDataRecord;
import io.vigier.cursorpaging.example.webapp.api.model.mapper.DtoDataRecordMapper;
import io.vigier.cursorpaging.example.webapp.model.DataRecord;
import io.vigier.cursorpaging.example.webapp.model.DataRecord_;
import io.vigier.cursorpaging.example.webapp.repository.DataRecordRepository;
import io.vigier.cursorpaging.jpa.Order;
import io.vigier.cursorpaging.jpa.PageRequest;
import io.vigier.cursorpaging.jpa.api.DtoPageRequest;
import io.vigier.cursorpaging.jpa.serializer.Base64String;
import io.vigier.cursorpaging.jpa.serializer.EntitySerializer;
import io.vigier.cursorpaging.jpa.validation.MaxSize;
import io.vigier.cursorpaging.testapp.api.model.DataRecordAttribute;
import io.vigier.cursorpaging.testapp.api.model.DtoDataRecord;
import io.vigier.cursorpaging.testapp.api.model.mapper.DtoDataRecordMapper;
import io.vigier.cursorpaging.testapp.model.DataRecord;
import io.vigier.cursorpaging.testapp.model.DataRecord_;
import io.vigier.cursorpaging.testapp.repository.DataRecordRepository;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.vigier.cursorpaging.testapp.api.model;
package io.vigier.cursorpaging.example.webapp.api.model;

import io.vigier.cursorpaging.example.webapp.model.AuditInfo;
import io.vigier.cursorpaging.example.webapp.model.AuditInfo_;
import io.vigier.cursorpaging.example.webapp.model.DataRecord_;
import io.vigier.cursorpaging.jpa.Attribute;
import io.vigier.cursorpaging.testapp.model.AuditInfo;
import io.vigier.cursorpaging.testapp.model.AuditInfo_;
import io.vigier.cursorpaging.testapp.model.DataRecord_;
import java.time.Instant;
import java.util.UUID;
import lombok.Getter;
Expand Down
Loading

0 comments on commit 87007bb

Please sign in to comment.