Skip to content

Commit 074bfe9

Browse files
committed
👉 docs(readme): finalize client usage with adapter and cross-microservice integration
1 parent e94ca09 commit 074bfe9

File tree

1 file changed

+100
-36
lines changed

1 file changed

+100
-36
lines changed

‎customer-service-client/README.md‎

Lines changed: 100 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ curl -s http://localhost:8084/customer-service/v3/api-docs.yaml \
6666
3. **Generate & build the client**
6767

6868
```bash
69-
mvn clean install
69+
mvn -q clean install
7070
```
7171

7272
### What got generated?
@@ -242,41 +242,10 @@ public class CustomerApiClientConfig {
242242
customer.api.base-url=http://localhost:8084/customer-service
243243
```
244244

245-
**Usage example:**
246-
247-
```java
248-
import io.github.bsayli.openapi.client.generated.api.CustomerControllerApi;
249-
import io.github.bsayli.openapi.client.generated.dto.CustomerCreateRequest;
250-
import io.github.bsayli.openapi.client.generated.dto.CustomerCreateResponse;
251-
import io.github.bsayli.openapi.client.common.ServiceClientResponse;
252-
import org.springframework.beans.factory.annotation.Autowired;
253-
import org.springframework.stereotype.Component;
254-
255-
@Component
256-
public class CustomerClientExample {
257-
258-
private final CustomerControllerApi customerApi;
259-
260-
public CustomerClientExample(CustomerControllerApi customerApi) {
261-
this.customerApi = customerApi;
262-
}
263-
264-
public void createCustomer() {
265-
CustomerCreateRequest req = new CustomerCreateRequest()
266-
.name("Jane Doe")
267-
.email("[email protected]");
268-
269-
ServiceClientResponse<CustomerCreateResponse> resp = customerApi.createCustomer(req);
270-
271-
System.out.println(resp.getStatus()); // 201
272-
System.out.println(resp.getData().getCustomer().getName()); // "Jane Doe"
273-
}
274-
}
275-
```
276-
277-
> Tip — The return type is strongly typed: `ServiceClientResponse<CustomerCreateResponse>`.
278-
> You can safely navigate `resp.getData().getCustomer()` without casting.
279-
> Handle non-2xx via Spring exceptions (e.g., `HttpClientErrorException`) as usual.
245+
> **Note — demo only:**
246+
> The configuration above wires the generated client beans for quick local demos.
247+
> In production, you should encapsulate `CustomerControllerApi` behind your own Adapter (see [âś… Using the Client in Another Microservice](#-using-the-client-in-another-microservice) below).
248+
> This keeps generated code isolated and lets your services depend only on stable adapter interfaces.
280249
281250
---
282251

@@ -441,6 +410,101 @@ This ensures:
441410

442411
---
443412

413+
## đź”— Using the Client in Another Microservice
414+
415+
When another microservice (e.g., `payment-service`) depends on `customer-service-client`, the recommended approach is to wrap the generated adapter behind a stable interface in your own project.
416+
417+
This keeps generated code fully encapsulated and exposes only a clean contract to the rest of your service.
418+
419+
---
420+
421+
### Example Structure in `payment-service`
422+
423+
```
424+
com.example.payment.client.customer
425+
├─ CustomerServiceClient.java (interface)
426+
└─ CustomerServiceClientImpl.java (implementation using injected adapter)
427+
```
428+
429+
### Interface
430+
431+
```java
432+
package com.example.payment.client.customer;
433+
434+
import io.github.bsayli.openapi.client.common.ServiceClientResponse;
435+
import io.github.bsayli.openapi.client.generated.dto.*;
436+
437+
public interface CustomerServiceClient {
438+
439+
ServiceClientResponse<CustomerCreateResponse> createCustomer(CustomerCreateRequest request);
440+
441+
ServiceClientResponse<CustomerDto> getCustomer(Integer customerId);
442+
443+
ServiceClientResponse<CustomerListResponse> getCustomers();
444+
445+
ServiceClientResponse<CustomerUpdateResponse> updateCustomer(Integer customerId, CustomerUpdateRequest request);
446+
447+
ServiceClientResponse<CustomerDeleteResponse> deleteCustomer(Integer customerId);
448+
}
449+
```
450+
451+
### Implementation
452+
453+
```java
454+
package com.example.payment.client.customer;
455+
456+
import io.github.bsayli.openapi.client.adapter.CustomerClientAdapter;
457+
import io.github.bsayli.openapi.client.common.ServiceClientResponse;
458+
import io.github.bsayli.openapi.client.generated.dto.*;
459+
import org.springframework.stereotype.Service;
460+
461+
@Service
462+
public class CustomerServiceClientImpl implements CustomerServiceClient {
463+
464+
private final CustomerClientAdapter adapter;
465+
466+
public CustomerServiceClientImpl(CustomerClientAdapter adapter) {
467+
this.adapter = adapter;
468+
}
469+
470+
@Override
471+
public ServiceClientResponse<CustomerCreateResponse> createCustomer(CustomerCreateRequest request) {
472+
return adapter.createCustomer(request);
473+
}
474+
475+
@Override
476+
public ServiceClientResponse<CustomerDto> getCustomer(Integer customerId) {
477+
return adapter.getCustomer(customerId);
478+
}
479+
480+
@Override
481+
public ServiceClientResponse<CustomerListResponse> getCustomers() {
482+
return adapter.getCustomers();
483+
}
484+
485+
@Override
486+
public ServiceClientResponse<CustomerUpdateResponse> updateCustomer(Integer customerId, CustomerUpdateRequest request) {
487+
return adapter.updateCustomer(customerId, request);
488+
}
489+
490+
@Override
491+
public ServiceClientResponse<CustomerDeleteResponse> deleteCustomer(Integer customerId) {
492+
return adapter.deleteCustomer(customerId);
493+
}
494+
}
495+
```
496+
497+
### Why This Matters
498+
499+
* **Encapsulation**: Generated code (`CustomerControllerApi`, DTOs, wrappers) stays hidden.
500+
* **Stable API**: Your microservice depends only on `CustomerServiceClient`.
501+
* **Flexibility**: If client generation changes, your service contract remains intact.
502+
* **Consistency**: All outbound calls to `customer-service` go through one interface.
503+
504+
âś… With this pattern, you can safely evolve generated clients without leaking implementation details across microservices.
505+
506+
---
507+
444508
## đź§© How the Generics Work
445509

446510
The template at `src/main/resources/openapi-templates/api_wrapper.mustache` emits wrappers like:

0 commit comments

Comments
 (0)