Skip to content

Commit b0a06b0

Browse files
committed
Add pact mock server
1 parent 34e9ae8 commit b0a06b0

File tree

6 files changed

+243
-25
lines changed

6 files changed

+243
-25
lines changed

README.md

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,10 @@
22

33
Herzlich willkommen zum Workshop API Design.
44

5-
## Aufgabe: Design einer RESTful API
5+
## Aufgabe: Erstellung von Consumer Contracts
66

7-
Bitte designen Sie eine API zur Kundenverwaltung.
8-
- Man kann sich alle Kunden anschauen
9-
- Man kann einen Kunden anlegen
10-
- Man kann sich die Detail-Informationen eines Kunden anschauen
11-
- Ein Kunde hat bis zu zwei Adressen:
12-
eine Rechnungsadresse und eine Lieferadresse
13-
- Man kann die Rechnungsadresse und die Lieferadresse ändern.
7+
Erstellen Sie einen Consumer Contract, der folgende Use Cases abdeckt:
148

15-
## Verwendung des Swagger-Editors
16-
17-
Bitte beschreiben Sie die API im OpenAPI-Format.
18-
Verwenden Sie dazu den Swagger-Editor
19-
20-
### Starten des Swagger-Editors
21-
22-
Mit folgendem Befehl kann der Swagger-Editor gestartet werden:
23-
```
24-
docker compose up
25-
```
26-
27-
### Öffnen des Swagger-Editors
28-
29-
Der Swagger-Editor kann über folgenden Link aufgerufen werden:
30-
[Swagger Editor](http://localhost:6060).
9+
- Betrachten der Details von Kunde `0815`
10+
- Versuch, den nicht existierenden Kunden `0817` zu betrachten
11+
- Ändern der Rechnungsadresse des Kunden `0815`

docker-compose.yaml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,17 @@ services:
33
image: "swaggerapi/swagger-editor:v5.0.0-alpha.81-unprivileged"
44
ports:
55
- "6060:8080"
6-
6+
pact-mock-server:
7+
image: pactfoundation/pact-cli:1.1.0.1
8+
command: "mock-service --consumer customer-spa --provider customer-service -p 1234 --host 0.0.0.0 --pact-dir /tmp/pacts"
9+
volumes:
10+
- "./pacts:/tmp/pacts"
11+
ports:
12+
- "1234:1234"
13+
hurl:
14+
image: ghcr.io/orange-opensource/hurl:4.3.0
15+
command: "--retry 5 --test /home/setup-pact-mock.hurl /home/customers.hurl /home/teardown-pact-mock.hurl"
16+
volumes:
17+
- "./hurl:/home"
18+
depends_on:
19+
- pact-mock-server

hurl/customers.hurl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
GET http://pact-mock-server:1234/customers
2+
3+
HTTP 200
4+
[Asserts]
5+
jsonpath "$[0].name" == "Max Mustermann"
6+
jsonpath "$[1].name" == "Erika Mustermann"
7+
jsonpath "$[2].name" == "James Bond"

hurl/setup-pact-mock.hurl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
DELETE http://pact-mock-server:1234/interactions
2+
X-Pact-Mock-Service: true
3+
4+
POST http://pact-mock-server:1234/interactions
5+
X-Pact-Mock-Service: true
6+
{
7+
"description": "A request to get all customers",
8+
"consumer": "customer-client",
9+
"provider": "customer-service",
10+
"request": {
11+
"path": "/customers",
12+
"method": "GET"
13+
},
14+
"response": {
15+
"status": 200,
16+
"headers": {
17+
"Content-Type": "application/json"
18+
},
19+
"body": [
20+
{
21+
"name": "Max Mustermann",
22+
"number": "0815"
23+
},
24+
{
25+
"name": "Erika Mustermann",
26+
"number": "0816"
27+
},
28+
{
29+
"name": "James Bond",
30+
"number": "007"
31+
}
32+
]
33+
}
34+
}

hurl/teardown-pact-mock.hurl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
GET http://pact-mock-server:1234/interactions/verification
2+
X-Pact-Mock-Service: true
3+
4+
POST http://pact-mock-server:1234/pact
5+
X-Pact-Mock-Service: true
6+
Content-Length: 0

openapi.yaml

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
openapi: 3.1.0
2+
info:
3+
title: Customer Service
4+
version: 1.0.0
5+
servers:
6+
- url: http://localhost:9081/customer-service
7+
paths:
8+
/customers:
9+
get:
10+
operationId: getCustomers
11+
responses:
12+
"200":
13+
description: All customers, if they are less than ten
14+
content:
15+
application/json:
16+
schema:
17+
$ref: '#/components/schemas/CustomerCollection'
18+
post:
19+
operationId: createCustomer
20+
requestBody:
21+
content:
22+
application/json:
23+
schema:
24+
$ref: '#/components/schemas/Customer'
25+
required: true
26+
responses:
27+
"201":
28+
description: Customer is created
29+
headers:
30+
Location:
31+
description: The url of the created customer
32+
explode: false
33+
schema:
34+
pattern: "http\\://[a-z-]+[\\:[0-9]+]/orders/[0-9]+"
35+
type: string
36+
style: simple
37+
/customers/{customer_number}:
38+
get:
39+
operationId: getCustomerDetails
40+
parameters:
41+
- explode: false
42+
in: path
43+
name: customer_number
44+
required: true
45+
schema:
46+
type: string
47+
responses:
48+
"200":
49+
description: The details of one customer
50+
content:
51+
application/json:
52+
schema:
53+
$ref: '#/components/schemas/Customer'
54+
/customers/{customer_number}/addresses:
55+
get:
56+
operationId: getAddressesOfCustomer
57+
parameters:
58+
- explode: false
59+
in: path
60+
name: customer_number
61+
required: true
62+
schema:
63+
type: string
64+
responses:
65+
"200":
66+
description: The addresses of one customer
67+
content:
68+
application/json:
69+
schema:
70+
$ref: '#/components/schemas/AddressCollection'
71+
/customers/{customer_number}/addresses/{address_type}:
72+
get:
73+
operationId: getAddressOfType
74+
parameters:
75+
- explode: false
76+
in: path
77+
name: customer_number
78+
required: true
79+
schema:
80+
type: string
81+
- explode: false
82+
in: path
83+
name: address_type
84+
required: true
85+
schema:
86+
$ref: '#/components/schemas/AddressType'
87+
responses:
88+
"200":
89+
description: The addresses of one customer
90+
content:
91+
application/json:
92+
schema:
93+
$ref: '#/components/schemas/Address'
94+
put:
95+
operationId: setAddressOfType
96+
parameters:
97+
- explode: false
98+
in: path
99+
name: customer_number
100+
required: true
101+
schema:
102+
type: string
103+
- explode: false
104+
in: path
105+
name: address_type
106+
required: true
107+
schema:
108+
type: string
109+
requestBody:
110+
content:
111+
application/json:
112+
schema:
113+
$ref: '#/components/schemas/Address'
114+
responses:
115+
"204":
116+
description: Address was changed
117+
components:
118+
schemas:
119+
Customer:
120+
example:
121+
customer_umber: "0815"
122+
name: "Max Mustermann"
123+
properties:
124+
customer_number:
125+
pattern: \d+
126+
type: string
127+
readOnly: true
128+
name:
129+
type: string
130+
required:
131+
- customer_number
132+
- name
133+
CustomerCollection:
134+
type: array
135+
description: An array of customers
136+
items:
137+
$ref: '#/components/schemas/Customer'
138+
minItems: 0
139+
maxItems: 10
140+
Address:
141+
example:
142+
type: "billing"
143+
street: "Poststr."
144+
house_number: "1"
145+
zip_code: "26122"
146+
city: "Oldenburg"
147+
properties:
148+
type:
149+
ref$: '#/components/schemas/AddressType'
150+
street:
151+
minLength: 2
152+
type: string
153+
house_number:
154+
minLength: 1
155+
type: string
156+
zip_code:
157+
pattern: "\\d{5}"
158+
type: string
159+
city:
160+
minLength: 1
161+
type: string
162+
required:
163+
- city
164+
- street
165+
- zip_code
166+
AddressType:
167+
type: string
168+
x-extensible-enum:
169+
- billing
170+
- delivery
171+
AddressCollection:
172+
type: array
173+
description: An array of addresses
174+
items:
175+
$ref: '#/components/schemas/Address'
176+
minItems: 0
177+
maxItems: 10

0 commit comments

Comments
 (0)