overview of last week - ut · overview of last week ddd & data access luciano garcÍa-baÑuelos...

Post on 29-May-2020

1 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Overviewoflastweek

DDD&DATAACCESSLUCIANOGARCÍA-BAÑUELOS 1

Application

Domain model

JPAadapterWeb UI

adapter

SalesServiceSalesController

PlantDTO

PlantRepository

Plant

OrdersRepository

PurchaseOrder

PODTO

Apictureoftodayslecture• Whatiftheexecutionofanenterprisesoftwarespansacrosstheboundariesofanorganization?◦ Goal:Interoperability◦ Challenges:Distribution,Heterogeneity, Loose-coupling,Security,etc.

• Ourfocuswillbeontwoarchitecturalstyles:◦ REST:Resourceorientedarchitecture

◦ SOA:Serviceorientedarchitecture

RESTLUCIANOGARCÍA-BAÑUELOS 2

Enterprisesoftw

are Presentation

Application logic

Dataaccess

Integrationlayer

Presentation

Application logic

Dataaccess

ServiceAnalysis&Design• ServiceAnalysis. identificationanddefinitionofthebusinessservices thatanorganizationprovidesorconsumes,internallyorexternally.

à Collectionofbusiness-level services,theircontextand theirinteractions

• ServiceAPIDesign. identificationanddefinitionoftechnicalservices(e.g.REST)tosupportthedeliveryofbusinessservices.

à CollectionofserviceAPIs(operations, inputs&outputs)

Decomposing InformationSystems

1. Functionalorcapability-drivendecomposition• Whichbusiness functions, capabilitiesorspecializationperformworkinthe

organization(organizational chart)

2. Process-drivendecomposition• Whichchainsofactivitiescreatevaluetotheorganization?

3. Data-drivendecomposition• Whatinformation isstored&circulatesintheorganization?

ServiceAnalysis andDesignMethodsCapability-drivenmethods• SteveJones:EnterpriseSOAAdoptionStrategies.InfoQ,2005.

Process-drivenmethods• ThomasErl:“Service-OrientedArchitecture,Concepts,Technology,andDesign”,PrenticeHall,2005

Data-drivenmethods• PetriSelonen:FromRequirementstoaRESTfulWebService.InREST:FromResearchtoPractice,Springer,2011

Outlook

DDD&DATAACCESSLUCIANOGARCÍA-BAÑUELOS 6

Application

Domain model

JPAadapterWeb UI

adapter

SalesService

PlantRepository

Plant

OrdersRepository

PurchaseOrder

SalesController

PlantDTOPODTO

RESTadapter

BuilditSalesRestController

PlantDTO’PODTO’

Theprobleminanutshell

RESTLUCIANOGARCÍA-BAÑUELOS 7

ServerClient

Request

Response

• Anapplicationprogramminginterface (API)specifieshowsomesoftwarecomponentsshouldinteractwitheachother

• OurproblemconsistsindesigningAPIsforsomeofthecomponentsintheenterprisesoftware

Capability-driven ServiceAnalysis• Service

◦ Sub-systemwhereacollectionoftasksareperformed toachieveagoal.

• Actor◦ Useror“external”system(application) thatinteractswithagivenservice

• Interaction◦ Anencounterbetweentwoservicesorbetweenanactorandaserviceto

achieveagoal.◦ Includes:physicalorelectronic,manualorautomatic

Capability-driven ServiceAnalysisdefinition of the services scope: what the services are

external actors driving or interacting with the services

reasons of the service-to-service and service-to-actor interactions

details of services to be delivered by the IT team

Services

Actors

Interactions

API Design (resources & operations)

WHAT

WHO

WHY

HOW

Capability-drivenAnalysis– LevelsTheframeworkisappliedatincreasinglyfinerlevelsofgranularity

• Level0.Definitionofthecoreservicestothebusinessdomain.Level1.DecompositionoftheLevel0modelintofiner-grainedservicesforeachcoreservice.

• Level2+ Refinementsofpreviouslevelstoidentifysupport&sharedservicesintegrating&complementingtheservicesalreadydefined.

“Level0”ContextDiagram

Customer

SuppliersLogistics Company

MakeItem(s)

Ship Order Add to StockShip Order Bill Customer

Invoice

InvoicePayment

Order

Supply

Deliver

Deliver

Contact

OrderCheck Stock

Manufacture Sales

Logistics & Warehouse Finance

What

Who

Why

Rule of thumb:2-8 services at this level

“Level1”ContextDiagram(Manufacture)What

Who

Why

Research & Development Supplies In

Regulatory Approval Product Manufacture

Regulator

Send For Approval ManufactureTest Final Product

Request newsupplies

ManageApproval

Verify

Verify Supplies

Quality Control

Packaging

Order Supplies Stock Management

Request Stock / Add Stock

TestProduct

Finish

Request Stock / Add Stock

Supply Stock

External

Manufacture

Sales

Logistics & Warehouse

Finance

Process-DrivenServiceDesign1. Identifywhichprocess(es)needtobesupportedandtheiractors

2. Captureeachprocess(e.g.asaprocessmodel)

3. Analyzetasks/eventsinprocessmodeltoidentify:◦ Atomicinteractions(operations) thattheprocessshouldprovide◦ Atomicinteractions(operations) thattheprocessrequires fromothersystems

Supplier

CustomerProcurement Service

Warehouse Inventory Control

Service

FinanceInvoicing Service

Inte

rface Inte

rface

Inte

rface

Supplier(Order Management Service)

Process-Driven ServiceDesignSteps1.IdentifyingProcess&Actors

Process we need to support

Service Required by Process

Service Required by Process

External Actor

Process-Driven ServiceDesign2.CapturingtheOrderManagementProcess

Step3.Identifyoperations(OrderManagementService)Providedoperations(tocustomer)

• ReceiveRFQ

• Receiveorder

Requiredoperations

• Frominventorycontrol◦ Checkstockavailability◦ Requestorder shipment

• Invoicing◦ Requestinvoicing

Step3.IdentifyOperations• Lessobviousprovided operationsofordermanagementservice◦ Cancelorder/requestordercancellation◦ Modifyorder/request ordermodification◦ Checkorderstatus◦ …

Step3.IdentifyoperationsLessobviousrequired operations

• Topreparequote◦ Retrievepricelist◦ Retrievecustomerdata(contractualterms)

• Toprepareshipmentorder◦ Retrievecustomerdeliverydata

• Toprepareinvoicerequest◦ Retrievecustomerinvoicingdata

Rentit’s domain

DDD&DATAACCESSLUCIANOGARCÍA-BAÑUELOS 19

Plant catalogand purchase

orders

Maintenance plan

Plant reservation

Invoicing

Plant transportation

Domain

Maintenance

Reservations

Transportation

Invoicing

Sales(core)

Sub-domain

BoundedContext

Rentit’s domainmodel

DDD&DATAACCESSLUCIANOGARCÍA-BAÑUELOS 20

PurchaseOrder

BusinessPeriod

Address

Comment

ContactPerson

siteAddr

notes

rentalPeriod

contact

Customerrepresentatives

orders

customer

PlantInventoryEntry

PlantInventoryItem

PlantReservation

MaintenancePlan

MaintenanceTask

BusinessPeriodBusinessPeriod

plant

stock

type

reservation

rentalplant

scheduleschedule

tasks

maintPlan

plant

plantSpec

reservation

*

*

*

*1

1

1

*

1

1

1

1

0..1

0..11

1

1

11

0..1PurchaseOrder

BusinessPeriod

Address

Comment

ContactPerson

siteAddr

notes

rentalPeriod

contact

Customerrepresentatives

orders

customer

PlantInventoryEntry

PlantInventoryItem

PlantReservation

MaintenancePlan

MaintenanceTask

BusinessPeriodBusinessPeriod

plant

stock

type

reservation

rentalplant

scheduleschedule

tasks

maintPlan

plant

plantSpec

reservation

*

*

*

*1

1

1

*

1

1

1

1

0..1

0..11

1

1

11

0..1

Examplerepository

DDD&DATAACCESSLUCIANOGARCÍA-BAÑUELOS 21

Data-DrivenServiceDesign• SuitableparticularlyforRESTfulservicedesign

• Startsfromadatamodel

• Keyentitiesinmodelbecome“resources”

• CRUDframeworkusedtoidentifyoperations

• Onepossiblemethod(youmustreadit!):◦ PetriSelonen:FromRequirementstoaRESTfulWebService.InREST:FromResearchtoPractice,Springer,2011

Data-DrivenServiceDesign1. Capturedomainmodel◦ High-leveldatamodel

2. Refinedomainmodelintoresourcemodel◦ Identifyresourcesofdifferent typesandhypermedia relations

3. DeriveRESTAPI◦ UseCRUD(orSCRUD)framework

REST•RESTstandsforRepresentationalStateTransfer◦ Introduced/definedin2000byRoyFieldinginhisDoctoralDissertation

◦ BTW,FieldingisoneoftheprincipalauthorsofHTTPspecificationversions1.0and1.1

•RESTisanarchitecturestylefordesigningnetworkedapplications◦ Inmanyways,theWorldWideWeb itself,canbeviewedasaREST-basedarchitecture

•RESTisnotanstandardnoraproductØ Incontrast,SOAP,WSDLandaplethoraofWS-*standardsprovideafoundationforSOAontheWeb

RESTLUCIANOGARCÍA-BAÑUELOS 24

(Conceptual)buildingblocks

RESTLUCIANOGARCÍA-BAÑUELOS 25

URI

HTTP

Hypermedia

Resourceidentifiere.g.,http://en.wikipedia.org/wiki/Representational_State_Transfer

InteractionprotocolMethods:GET,POST,PUT,DELETE,etc.

Statuscodes:200Ok,404Notfound, etc.Metadata:Contentformat,Location,etc.

InteractionmodelTraversalofhyperlinks

Approachnumber1• Foreachresourceidentifiedinyoursystem,listallpossibleoperation andassociateauniqueURItoeachofthem

RESTLUCIANOGARCÍA-BAÑUELOS 26

/getPlant/getAllPlants/isPlantAvailable

/createPurchaseOrder/acceptPurchaseOrder/rejectPurchaseOrder/getPurchaseOrder/getAllPurchaseOrders/updatePurchaseOrder/isPurchaseOrderOpen/isPurchaseOrderPaid

/createInvoice/sendInvoiceToCustomer/getInvoiceStatus/acceptInvoice/rejectInvoice

/createPlantHireRequest/acceptPlantHireRequest/rejectPlantHireRequest/updatePlantHireRequest

/createRemittanceAdivice/createInvoiceResponse/createCreditNote...

Example

RESTLUCIANOGARCÍA-BAÑUELOS 27

Plant

name: Stringdescription: Stringprice: Float

Customer

name: StringvatNumber: String

PurchaseOrder

start: Dateend: Datecost: Floatstatus: POStatus

«resource instance» Plant

name: Stringdescription: Stringprice: Float

«resource instance» PurchaseOrder

start: Dateend: Datecost: Float

«resource instance» Plant

name: Stringdescription: Stringprice: Float

«resource instance» PurchaseOrder

start: Dateend: Datecost: Float

Example:Resourcemodel

RESTLUCIANOGARCÍA-BAÑUELOS 28

«container» PurchaseOrders

«container» Plants

«container» POPlants

«root» RentIt REST endpoint

{URI http://rentit.com/rest}

http://rentit.com/rest/pos

http://rentit.com/rest/pos/{po.id}/plants

http://rentit.com/rest/pos/{po.id}

HTTPverbs&behaviormodel• Convenienceoperations◦ HEAD Retrievesmetadata◦ OPTIONS Askswhichmethodsaresupportedbyaresource

• Basicoperations◦ GET Retrievesarepresentationforagivenresource◦ DELETE Deletesanexistingresource

• Otheroperations◦ PUT Canbeusedforcreatingorreplacingaresource◦ POST Canalsobeusedforcreatingorupdatingaresource◦ PATCH Updatesaresource

RESTLUCIANOGARCÍA-BAÑUELOS 29

ResourcecreationwithPOST

RESTLUCIANOGARCÍA-BAÑUELOS 30

RentItBuildIt

POST /poshttp://rentit.com/rest

<purchaseOrder><rentalPeriod><start>2017-06-21</start><end>2017-06-24</end>

<rentalPeriod><plant><name>Excavator</name>

<plant></purchaseOrder>

HTTP/1.1201CreatedLocation: /pos/1253

Resourceretrieval

RESTLUCIANOGARCÍA-BAÑUELOS 31

RentItBuildIt

GET /pos/1253http://rentit.com/rest

HTTP/1.1200Ok<purchaseOrder>

<id>1253</id><rentalPeriod><start>2017-06-21</start><end>2017-06-24</end>

<rentalPeriod><cost>1500.00</cost><plant><name>Excavator</name>

<plant><status>OPEN</status>

</purchaseOrder>

Resource creation: PUTvs.POST• IfPUTisused,then:◦ theresourceidentifier issetbytheclient

◦ thefullrepresentationoftheresourceisalwaysprovided

RESTLUCIANOGARCÍA-BAÑUELOS 32

☛ UsePUTonly inscenarioswherea“fullreplacement” oftheresourcerepresentationisimplied

• IfPOSTisused,then:◦ theresourceidentifier issetbytheserver

◦ onlyapartoftherepresentationneedstobeexchanged

<purchaseOrder><id>1253</id><start>2016-03-21</start><end>2016-03-24</end><cost>1500.00</cost><plant>

<name>Excavator</name><plant><status>OPEN</status>

</purchaseOrder>

<purchaseOrder><start>2016-03-21</start><end>2016-03-24</end><plant>

<name>Excavator</name><plant>

</purchaseOrder>

PUT /pos/1235 POST /pos

Updating theresources (take1)• Sofar,thereisnotconsensusonhowtoimplementthe"update"operationonresources◦ SomesaythatweshouldusePUT.Butshouldweusefullorpartialrepresentation?

◦ SomeotherssaythatweshouldusePOST

• Toavoidambiguitywewilldothefollowing:◦ POST Creation◦ PUT Replacement◦ PATCH Partialupdate

• Butthisisjustaconventionandnotanorm

RESTLUCIANOGARCÍA-BAÑUELOS 33

<purchaseOrder><end>2016-03-31</end>

</purchaseOrder>PATCH /pos/1235

URIpatternsandHTTPverbs

RESTLUCIANOGARCÍA-BAÑUELOS 34

URI HTTPverb Comments

/pos GET Retrieveallpurchaseorders

POST Create newpurchaseorder

/pos/{po.id} GET Retrieveaspecific purchaseorder

PATCH Updateapurchaseorder

DELETE Removeapurchaseorder

/pos/{po.id}/plants GET Retrieveallplantsassociatedtoagivenpurchaseorder

POST Addaplanttoagiven purchaseorder

/pos/{po.id}/plants/{plant.id} GET Retrieve aspecificplantwithinapurchaseorder

PATCH Modify aplant?

DELETE Remove aplantfromapurchaseorder

Queryingandfiltering• Insomecases,wewillneedtorestrictourattentiontoasubsetofresourceinstances:◦ Onlyopenpurchaseorders◦ Invoiceswithinafiscalperiod

• Itisalsointerestingtousecertaincriteriawhenqueryinga“container”◦ Setofplantsofcertaincapacitiesandavailableinforagivenperiodof time

• Inthosecases,useURIquerytemplatesoftheform:

• Note:AlltheaboveURIsshouldberequestedviaanHTTPGET

RESTLUCIANOGARCÍA-BAÑUELOS 35

GET/plants?name=excavator

GET/phrs?status=OPEN

HTTPstatuscodes• TheHTTPstatuscodesprovidemetadataaboutthestateofresources

• TheyarepartofwhatmakestheWebarichplatformforbuildingdistributedsystems

• Theycoverfivebroadcategories◦ 1xx– Metadata

◦ 2xx– Everything’s fine

◦ 3xx– Redirection

◦ 4xx– Clientdidsomething wrong

◦ 5xx– Serverdidabadthing

RESTLUCIANOGARCÍA-BAÑUELOS 36

Thehappypath:

200 Ok201 Created202 Accepted204 Nocontent

“Location”shouldcontaintheURIforaccessingtheresourcewhenever itbecomesavailable:• 201– immediately• 202– subsequently

HTTPstatuscodes• TheHTTPstatuscodesprovidemetadataaboutthestateofresources

• TheyarepartofwhatmakestheWebarichplatformforbuildingdistributedsystems

• Theycoverfivebroadcategories◦ 1xx– Metadata

◦ 2xx– Everything’s fine

◦ 3xx– Redirection

◦ 4xx– Clientdidsomething wrong

◦ 5xx– Serverdidabadthing

RESTLUCIANOGARCÍA-BAÑUELOS 37

Exceptionnotification:

400 Badrequest404 Notfound405 Methodnotallowed406 Notacceptable409 Conflict

Implementingtheintegrationlayer

RESTLUCIANOGARCÍA-BAÑUELOS 38

Domainobjectvs.Resource

RESTLUCIANOGARCÍA-BAÑUELOS 39

@Entity@Getterpublic class Plant {

@Idprivate Long id;private String name;private String description;private BigDecimal price;

}

@Datapublic class PlantDTO extendsResourceSupport {

private Long _id;private String name;private String description;private BigDecimal price;

}

public class PlantAssembler extendsResourceAssemblerSupport<Plant, PlantDTO> {public PlantAssembler() {

super(InventoryRestController.class, PlantDTO.class);}public PlantDTO toResource(Plant plant) {

...}public List<PlantDTO> toResource(List<Plant> plants) {

...}

}

Package:~.application.service

Package:~.application.dtoPackage:~.domain.model

RESTservicefaçade

RESTLUCIANOGARCÍA-BAÑUELOS 40

@RestController@RequestMapping("/api/orders")public class PurchaseOrderRestController {

@RequestMapping(method = RequestMethod.GET, path = "")public List<PurchaseOrderResource> getAllPOs() {

...}

@PostMappingpublic ResponseEntity<Plant> createPO(@RequestBody PurchaseOrderResource res) {

...}

@GetMapping("/pos/{id}")public PurchaseOrderResource getPO(@PathVariable Long id) {

...}

@PostMapping("/pos/{id}/plants")public ResponseEntity<PurchaseOrderResource> addPlantToPO(@PathVariable Long id,

@RequestBody PlantResource res) {...

}}

Resourcecreation

RESTLUCIANOGARCÍA-BAÑUELOS 41

@RestController@RequestMapping("/api/orders")public class PurchaseOrderRestController {

@AutowiredSalesService salesService;

@PostMappingpublic ResponseEntity<PurchaseOrderDTO> createPO(

@RequestBody PurchaseOrderDTO inputPO) {

PurchaseOrderDTO po = salesService.createPO(inputPO);

HttpHeaders headers = new HttpHeaders();URI location = ServletUriComponentsBuilder.fromCurrentRequestUri().

pathSegment(po.get_id()).build().toUri();headers.setLocation(location);

return new ResponseEntity<>(po, headers, HttpStatus.CREATED);

}}

Example

RESTLUCIANOGARCÍA-BAÑUELOS 42

$ curl -v -X POST -H "Content-type: application/xml" \-d @po.xml http://localhost:8080/api/orders

> POST /api/orders HTTP/1.1> Host: localhost:8080> Accept: */*> Content-type: application/xml

< HTTP/1.1 201 Created< Location: http://localhost:8080/api/orders/1

Retrievingaresource

RESTLUCIANOGARCÍA-BAÑUELOS 43

@RestController@RequestMapping("/api/orders")public class PurchaseOrderRestController {

@AutowiredSalesService salesService;

@GetMapping@ResponseStatus(HttpStatus.OK)public List<PurchaseOrderDTO> getAllPOs() {

return salesService.findAllPurchaseOrders();}

}

Contentnegotiation

RESTLUCIANOGARCÍA-BAÑUELOS 44

$curl-H"Accept:application/json"http://localhost:8080/api/orders<HTTP/1.1200OK<Content-Type:application/json;charset=UTF-8

{"purchaseOrder":[{

"startDate":1381093200000,"endDate":1381438800000,"total":1250.0,"plant":null

}]}

Contentnegotiation

RESTLUCIANOGARCÍA-BAÑUELOS 45

$curl-H"Accept:application/xml"http://localhost:8080/api/orders

<HTTP/1.1200OK<Content-Type:application/xml;charset=UTF-8

<?xmlversion="1.0"encoding="UTF-8"standalone="yes"?><purchaseOrders>

<purchaseOrder><endDate>2013-10-11T00:00:00+03:00</endDate><startDate>2013-10-07T00:00:00+03:00</startDate><total>1250.0</total>

</purchaseOrder></purchaseOrders>

ExceptionhandlingwithinourRESTcontroller

46

@RestController@RequestMapping("/api/orders")public class PurchaseOrderRestController {

@ExceptionHandler({PlantUnavailableException.class, InvalidRentalPeriodException.class})

public ResponseEntity<String> handleBadRequest(Exception ex) {return new ResponseEntity<>(ex.getMessage(), HttpStatus.CONFLICT);

}

@ExceptionHandler(EntityNotFoundException.class)public ResponseEntity<String> handleNotFound(Exception ex) {

return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);}

}

RESTLUCIANOGARCÍA-BAÑUELOS

top related