Skip to content
This repository has been archived by the owner on Dec 17, 2024. It is now read-only.

Commit

Permalink
feat: provide hal based structure for agency search
Browse files Browse the repository at this point in the history
  • Loading branch information
mebo4b committed Nov 12, 2020
1 parent 20474d5 commit b446c7d
Show file tree
Hide file tree
Showing 16 changed files with 435 additions and 21 deletions.
78 changes: 73 additions & 5 deletions api/agencyadminservice.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ info:
servers:
- url: /
paths:
/:
get:
tags:
- root-controller
summary: 'Returns the hal root entry point. [Authorization: Role: agency-admin]'
operationId: getRoot
responses:
200:
description: OK - successfull operation
content:
application/hal+json:
schema:
$ref: '#/components/schemas/RootDTO'
security:
- Bearer: [ ]
/admin/agencies:
get:
tags:
Expand All @@ -21,7 +36,7 @@ paths:
type: string
- name: page
in: query
description: Number of page where to start in the query (0 = first page)
description: Number of page where to start in the query (1 = first page)
required: true
schema:
type: integer
Expand All @@ -35,11 +50,9 @@ paths:
200:
description: OK - successfull operation
content:
'application/json':
'application/hal+json':
schema:
type: array
items:
$ref: '#/components/schemas/AgencyAdminResponseDTO'
$ref: '#/components/schemas/AgencyAdminSearchResultDTO'
400:
description: BAD REQUEST - invalid/incomplete request or body object
500:
Expand All @@ -49,6 +62,47 @@ paths:

components:
schemas:
RootDTO:
type: object
required:
- _links
properties:
_links:
$ref: '#/components/schemas/RootLinks'

RootLinks:
type: object
required:
- self
properties:
self:
$ref: '#/components/schemas/halLink'
agencies:
$ref: '#/components/schemas/halLink'

HalLink:
type: object
required:
- href
properties:
href:
type: string
method:
type: string
enum: [ GET, POST, DELETE, PUT ]
templated:
type: boolean

AgencyAdminSearchResultDTO:
type: object
properties:
_embedded:
type: array
items:
$ref: '#/components/schemas/AgencyAdminResponseDTO'
_links:
$ref: '#/components/schemas/SearchResultLinks'

AgencyAdminResponseDTO:
type: object
properties:
Expand Down Expand Up @@ -102,6 +156,20 @@ components:
type: string
example: "79106"

SearchResultLinks:
type: object
required:
- self
properties:
self:
$ref: '#/components/schemas/halLink'
next:
$ref: '#/components/schemas/halLink'
previous:
$ref: '#/components/schemas/halLink'
search:
$ref: '#/components/schemas/halLink'

securitySchemes:
Bearer:
type: apiKey
Expand Down
4 changes: 4 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package de.caritas.cob.agencyservice.api.admin.controller;

import de.caritas.cob.agencyservice.api.admin.service.AgencyAdminSearchResultBuilder;
import de.caritas.cob.agencyservice.api.model.AgencyAdminResponseDTO;
import de.caritas.cob.agencyservice.api.model.AgencyAdminSearchResultDTO;
import de.caritas.cob.agencyservice.generated.api.controller.AdminApi;
import io.swagger.annotations.Api;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import lombok.NonNull;
Expand All @@ -13,20 +12,32 @@
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;

/**
* Controller to handle all agency admin requests.
*/
@RestController
@Api(tags = "agency-admin-controller")
@RequiredArgsConstructor
public class AgencyAdminController implements AdminApi {

private final @NonNull AgencyAdminSearchResultBuilder agencyAdminSearchResultBuilder;

/**
* Entry point to search for agencies.
*
* @param page Number of page where to start in the query (1 = first page) (required)
* @param perPage Number of items which are being returned (required)
* @param q The query parameter to search for (optional)
* @return a entity conatining the search result
*/
@Override
public ResponseEntity<List<AgencyAdminResponseDTO>> searchAgencies(@NotNull @Valid Integer page,
public ResponseEntity<AgencyAdminSearchResultDTO> searchAgencies(@NotNull @Valid Integer page,
@NotNull @Valid Integer perPage, @Valid String q) {

List<AgencyAdminResponseDTO> agencyAdminResponseDTOS = this.agencyAdminSearchResultBuilder
AgencyAdminSearchResultDTO agencyAdminSearchResultDTO = this.agencyAdminSearchResultBuilder
.buildAgencyAdminSearchResult(q, page, perPage);

return new ResponseEntity<>(agencyAdminResponseDTOS, HttpStatus.OK);
return new ResponseEntity<>(agencyAdminSearchResultDTO, HttpStatus.OK);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package de.caritas.cob.agencyservice.api.admin.hallink;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;

import de.caritas.cob.agencyservice.api.model.HalLink;
import de.caritas.cob.agencyservice.api.model.HalLink.MethodEnum;
import org.springframework.hateoas.Link;
import org.springframework.http.HttpEntity;

public interface HalLinkBuilder {

default HalLink buildHalLink(HttpEntity<?> httpEntity, MethodEnum method) {
Link link = linkTo(httpEntity).withSelfRel();
HalLink halLink = new HalLink();
halLink.setHref(link.getHref());
halLink.setMethod(method);
halLink.setTemplated(link.isTemplated());
return halLink;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package de.caritas.cob.agencyservice.api.admin.hallink;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;

import de.caritas.cob.agencyservice.api.model.HalLink;
import de.caritas.cob.agencyservice.api.model.HalLink.MethodEnum;
import de.caritas.cob.agencyservice.api.model.RootDTO;
import de.caritas.cob.agencyservice.api.model.RootLinks;
import de.caritas.cob.agencyservice.generated.api.controller.AdminApi;
import de.caritas.cob.agencyservice.generated.api.controller.DefaultApi;

/**
* Builder to create the root navigation hal DTO.
*/
public class RootDTOBuilder implements HalLinkBuilder {

private static final Integer DEFAULT_PAGE = 1;
private static final Integer DEFAULT_PER_PAGE = 20;

/**
* Builds the root navigation DTO.
*
* @return the {@link RootDTO} containing hal links
*/
public RootDTO buildRootDTO() {
return new RootDTO()
.links(new RootLinks()
.self(buildSelfLink())
.agencies(buildSearchLink()));
}

private HalLink buildSelfLink() {
return buildHalLink(methodOn(DefaultApi.class).getRoot(), MethodEnum.GET);
}

private HalLink buildSearchLink() {
return buildHalLink(
methodOn(AdminApi.class).searchAgencies(DEFAULT_PAGE, DEFAULT_PER_PAGE, null),
MethodEnum.GET);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package de.caritas.cob.agencyservice.api.admin.hallink;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;

import de.caritas.cob.agencyservice.api.model.HalLink;
import de.caritas.cob.agencyservice.api.model.HalLink.MethodEnum;
import de.caritas.cob.agencyservice.api.model.SearchResultLinks;
import de.caritas.cob.agencyservice.generated.api.controller.AdminApi;

/**
* Link builder to create hal links for search results.
*/
public class SearchResultLinkBuilder implements HalLinkBuilder {

private Integer page;
private Integer perPage;
private String keyword;

private SearchResultLinkBuilder() {}

/**
* Creates an {@link SearchResultLinkBuilder} instance.
*
* @return a instance of {@link SearchResultLinkBuilder}
*/
public static SearchResultLinkBuilder getInstance() {
return new SearchResultLinkBuilder();
}

/**
* Sets the page param.
*
* @param page the page value for building links
* @return the current {@link SearchResultLinkBuilder}
*/
public SearchResultLinkBuilder withPage(Integer page) {
this.page = page;
return this;
}

/**
* Sets the perPage param.
*
* @param perPage the amount value of results per page for building links
* @return the current {@link SearchResultLinkBuilder}
*/
public SearchResultLinkBuilder withPerPage(Integer perPage) {
this.perPage = perPage;
return this;
}

/**
* Sets the keyword search param.
*
* @param keyword the keyword value for building links
* @return the current {@link SearchResultLinkBuilder}
*/
public SearchResultLinkBuilder withKeyword(String keyword) {
this.keyword = keyword;
return this;
}

/**
* Creates the {@link SearchResultLinks}.
*
* @return the generated {@link SearchResultLinks}
*/
public SearchResultLinks buildSearchResultLinks() {
return new SearchResultLinks()
.self(buildSelfLink())
.next(buildNextLink())
.previous(buildPreviousLink())
.search(buildSearchLink());
}

private HalLink buildSelfLink() {
return buildHalLinkForParams(this.page, this.perPage, this.keyword);
}

private HalLink buildHalLinkForParams(Integer page, Integer perPage, String keyword) {
return buildHalLink(methodOn(AdminApi.class).searchAgencies(page, perPage, keyword),
MethodEnum.GET);
}

private HalLink buildNextLink() {
return buildHalLinkForParams(this.page + 1, this.perPage, this.keyword);
}

private HalLink buildPreviousLink() {
if (this.page > 1) {
return buildHalLinkForParams(this.page - 1, this.perPage, this.keyword);
}
return null;
}

private HalLink buildSearchLink() {
return buildHalLinkForParams(this.page, this.perPage, null);
}

}
Loading

0 comments on commit b446c7d

Please sign in to comment.