Appendix B

Implementation of the Lakeside Mutual Case

In this appendix, we return to the fictitious case we introduced in Chapter 2, “Lake-side Mutual Case Study.” Many examples from the case are provided in Part 2. Here, we feature selected specification and implementation details.

Pattern Application

Many of the patterns from this book were applied in the Lakeside Mutual case. Some examples follow:

  • The class InsuranceQuoteRequestProcessingResource.java in the Policy Management microservice is an activity-oriented PROCESSING RESOURCE, which is indicated by its name suffix. The data-oriented CustomerInformationHolder.java in the Customer Core service is an INFORMATION HOLDER RESOURCE.

  • The representation element customerProfile in CustomerDto.java applies DATA ELEMENT and EMBEDDED ENTITY.

  • A RATE LIMIT realization can be found in RateLimitInterceptor.java in the Customer Self-Service microservice.

A more complete overview is available in the GitHub repository of Lakeside Mutual.1 In the following, we provide two different views on the getCustomers RETRIEVAL OPERATION of the Customer Core INFORMATION HOLDER RESOURCE.

1. https://github.com/Microservice-API-Patterns/LakesideMutual/blob/master/MAP.md.

Java Service Layer

Figure 2.4 in Chapter 2 shows a domain model of the realized insurance business concepts; the Java Service Layer featured here implements parts of this domain model. Due to space constraints, we show only parts of each artifact here; a more complete implementation can be found in the GitHub repository.

This is the CustomerInformationHolder class that serves as a Spring @RestController:

@RestController
@RequestMapping("/customers")
public class CustomerInformationHolder {
/**
  * Returns a 'page' of customers.
  *
  * The query parameters {@code limit} and {@code offset} can be
  * used to specify the maximum size of the page and the offset of
  * the page's first customer.
  *
  * The response contains the customers, limit and offset of the
  * current page, as well as the total number of customers  * (data set size).
  * Additionally, it contains HATEOAS-style links that link to the
  * endpoint addresses of the current, previous, and next page.
  */
   @Operation(summary =
       "Get all customers in pages of 10 entries per page.")
   @GetMapping // operation responsibility: Retrieval Operation
   public ResponseEntity<PaginatedCustomerResponseDto>
       getCustomers(
     @RequestParam(
         value = "filter", required = false, defaultValue = "")
       String filter,
     @RequestParam(
         value = "limit", required = false, defaultValue = "10")
       Integer limit,
     @RequestParam(
         value = "offset", required = false, defaultValue = "0")
       Integer offset,
     @RequestParam(
         value = "fields", required = false, defaultValue = "")

         String fields) {

      String decodedFilter = UriUtils.decode(filter, "UTF-8");

      Page<CustomerAggregateRoot> customerPage = customerService
        .getCustomers(decodedFilter, limit, offset);

      List<CustomerResponseDto> customerDtos = customerPage
        .getElements()
        .stream()
        .map(c -> createCustomerResponseDto(c, fields))
        .collect(Collectors.toList());

      PaginatedCustomerResponseDto response =
        createPaginatedCustomerResponseDto(
          filter,
          customerPage.getLimit(),
          customerPage.getOffset(),
          customerPage.getSize(),
          fields,
          customerDtos);

    return ResponseEntity.ok(response);
  }

OpenAPI Specification and Sample API Client

Stepping back from the implementation details, the following OpenAPI specification (shortened for clarity) of the getCustomers operation from the Java Service Layer provides another view of the API design:

openapi: 3.0.1
info:
  title: Customer Core API
  description: This API allows clients to create new customers
    and retrieve details about existing customers.
  license:
    name: Apache 2.0
  version: v1.0.0
servers:

  - url: http://localhost:8110
    description: Generated server url
paths:
  /customers:
    get:
      tags:
        - customer-information-holder
      summary: Get all customers in pages of 10 entries per page.
      operationId: getCustomers
      parameters:
        - name: filter
          in: query
          description: search terms to filter the customers by
            name
          required: false
          schema:
            type: string
            default: ''
        - name: limit
          in: query
          description: the maximum number of customers per page
          required: false
          schema:
            type: integer
            format: int32
            default: 10
          - name: offset
            in: query
            description: the offset of the page's first customer
            required: false
            schema:
              type: integer
              format: int32
              default: 0
          - name: fields
            in: query
            description: a comma-separated list of the fields
              that should be included in the response
            required: false
            schema:
              type: string
              default: ''
        responses:
          '200':
            description: OK
            content:
              '*/*':
                schema:
                  $ref: "#/components/schemas
                         /PaginatedCustomerResponseDto"
        components:
          schemas:
            Address:
              type: object
              properties:
                streetAddress:
                  type: string
                postalCode:
                  type: string
                city:
                  type: string
            CustomerResponseDto:
              type: object
              properties:
                customerId:
                  type: string
                firstname:
                  type: string
                lastname:
                  type: string
                birthday:
                  type: string
                  format: date-time
                streetAddress:
                  type: string
                postalCode:
                  type: string
                city:
                  type: string
                email:
                  type: string
                phoneNumber:
                  type: string
                moveHistory:
                  type: array
                  items:
                    $ref: '#/components/schemas/Address'
                links:
                  type: array
                  items:
                    $ref: '#/components/schemas/Link'
          Link:
            type: object
             properties:
               rel:
                 type: string
               href:
                 type: string
          AddressDto:
            required:
              - city
              - postalCode
              - streetAddress
            type: object
            properties:
              streetAddress:
                type: string
              postalCode:
                type: string
              city:
                type: string
            description: the customer's new address
          PaginatedCustomerResponseDto:
            type: object
            properties:
              filter:
                type: string
              limit:
                type: integer
                format: int32
              offset:
                type: integer
                format: int32
              size:
                type: integer
                format: int32
              customers:
                type: array
                items:
                  $ref: '#/components/schemas/CustomerResponseDto'
            links:
              type: array
              items:
                $ref: '#/components/schemas/Link'

When querying the endpoint using curl, the following HTTP response is returned:

curl -X GET --header 
'Authorization: Bearer b318ad736c6c844b' 
http://localhost:8110/customers?limit=2

{
  "limit": 2,
  "offset": 0,
  "size": 50,
  "customers": [ {
    "customerId": "bunlo9vk5f",
    "firstname": "Ado",
    "lastname": "Kinnett",
    "birthday": "1975-06-13T23:00:00.000+00:00",
    "streetAddress": "2 Autumn Leaf Lane",
    "postalCode": "6500",
    "city": "Bellinzona",
    "email": "[email protected]",
    "phoneNumber": "055 222 4111",
    "moveHistory": [ ]
  }, {
    "customerId": "bd91pwfepl",
    "firstname": "Bel",
    "lastname": "Pifford",
    "birthday": "1964-02-01T23:00:00.000+00:00",
    "streetAddress": "4 Sherman Parkway",
    "postalCode": "1201",
    "city": "Genf",
    "email": "[email protected]",
    "phoneNumber": "055 222 4111",
    "moveHistory": [ ]
    } ],
    "_links": {
      "self": {
        "href": "/customers?filter=&limit=2&offset=0&fields="
      },
      "next": {
        "href": "/customers?filter=&limit=2&offset=2&fields="
    }
  }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.148.113.111