From 54a9c2a82c060ec54874964db90a05a5deaac3ae Mon Sep 17 00:00:00 2001 From: Jiaqi Liu Date: Thu, 3 Oct 2024 13:06:05 +0800 Subject: [PATCH] Replace all-in-one with paginated endpoint (#3) --- .gitignore | 1 + .../wilhelm/web/endpoints/DataServlet.java | 29 ++++++++++++------- .../web/endpoints/DataServletITSpec.groovy | 3 +- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index c6edaa3..a4498b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.iml .idea/ target/ +logback/ .DS_Store application.properties diff --git a/src/main/java/org/qubitpi/wilhelm/web/endpoints/DataServlet.java b/src/main/java/org/qubitpi/wilhelm/web/endpoints/DataServlet.java index f962819..000b668 100644 --- a/src/main/java/org/qubitpi/wilhelm/web/endpoints/DataServlet.java +++ b/src/main/java/org/qubitpi/wilhelm/web/endpoints/DataServlet.java @@ -15,8 +15,6 @@ */ package org.qubitpi.wilhelm.web.endpoints; -import org.qubitpi.wilhelm.config.ApplicationConfig; - import org.aeonbits.owner.ConfigFactory; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Driver; @@ -25,6 +23,7 @@ import org.neo4j.driver.QueryConfig; import org.neo4j.driver.Value; import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.qubitpi.wilhelm.config.ApplicationConfig; import jakarta.inject.Inject; import jakarta.inject.Singleton; @@ -33,6 +32,7 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import net.jcip.annotations.Immutable; @@ -62,10 +62,10 @@ public class DataServlet { private static final String NEO4J_DATABASE = APPLICATION_CONFIG.neo4jDatabase(); private static final Map LANGUAGES = Stream.of( - new AbstractMap.SimpleImmutableEntry<>("german", "German"), - new AbstractMap.SimpleImmutableEntry<>("ancientGreek", "Ancient Greek"), - new AbstractMap.SimpleImmutableEntry<>("latin", "Latin") - ) + new AbstractMap.SimpleImmutableEntry<>("german", "German"), + new AbstractMap.SimpleImmutableEntry<>("ancientGreek", "Ancient Greek"), + new AbstractMap.SimpleImmutableEntry<>("latin", "Latin") + ) .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue)); @@ -91,17 +91,23 @@ public Response healthcheck() { } /** - * Get all vocabularies of a language. + * Get paginated vocabularies of a language. * * @param language The language. Must be one of "german", "ancientGreek", or "latin". Otherwise a 404 response is * returned + * @param perPage Requested number of words to be displayed on each page of results + * @param page Requested page of results desired * - * @return the Neo4J query results in JSON format + * @return the paginated Neo4J query results in JSON format */ @GET @Path("/languages/{language}") @Produces(MediaType.APPLICATION_JSON) - public Response getVocabularyByLanguage(@NotNull @PathParam("language") final String language) { + public Response getVocabularyByLanguagePaged( + @NotNull @PathParam("language") final String language, + @NotNull @QueryParam("perPage") final String perPage, + @NotNull @QueryParam("page") final String page + ) { if (!LANGUAGES.containsKey(Objects.requireNonNull(language, "language"))) { return Response .status(Response.Status.BAD_REQUEST) @@ -116,8 +122,9 @@ public Response getVocabularyByLanguage(@NotNull @PathParam("language") final St final String query = String.format( "MATCH (t:Term WHERE t.language = '%s')-[r]->(d:Definition) " + - "RETURN t.name AS term, d.name AS definition", - LANGUAGES.get(language) + "RETURN t.name AS term, d.name AS definition " + + "SKIP %s LIMIT %s", + LANGUAGES.get(language), (Integer.parseInt(page) - 1) * Integer.parseInt(perPage), perPage ); try (Driver driver = GraphDatabase.driver(NEO4J_URL, AuthTokens.basic(NEO4J_USERNAME, NEO4J_PASSWORD))) { diff --git a/src/test/groovy/org/qubitpi/wilhelm/web/endpoints/DataServletITSpec.groovy b/src/test/groovy/org/qubitpi/wilhelm/web/endpoints/DataServletITSpec.groovy index 503ee08..65e2a6e 100644 --- a/src/test/groovy/org/qubitpi/wilhelm/web/endpoints/DataServletITSpec.groovy +++ b/src/test/groovy/org/qubitpi/wilhelm/web/endpoints/DataServletITSpec.groovy @@ -88,12 +88,13 @@ class DataServletITSpec extends Specification { .statusCode(200) } - def "Get vocabulary by language"() { + def "Get vocabulary by language and retrieve the very first word"() { expect: RestAssured .given() .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) + .queryParams([perPage: "10", page: "1"]) .when() .get("/data/languages/german") .then()