Process of Request and Response

Process of Request and Response

In a microservices architecture, services often need to communicate with each other to complete a request. This involves sending a request from one service to another and processing the response received. This can be achieved using synchronous or asynchronous communication methods.

Process of Request and Response

1. Synchronous Communication:

  • Uses HTTP/HTTPS protocols with REST APIs.
  • One service makes a direct call to another service and waits for the response.

2. Asynchronous Communication:

  • Uses message brokers like RabbitMQ or Kafka.
  • Services communicate by publishing messages to a queue or topic and subscribing to messages.

Synchronous Communication Example

  • Service A (User Service):
    • Provides user information based on a user ID.
  • Service B (Order Service):
    • Processes orders and fetches user information from the User Service.

User Service
```java
// UserServiceApplication.java
@SpringBootApplication
@RestController
@RequestMapping("/users")
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }

    @GetMapping("/{id}")
    public User getUserById(@PathVariable String id) {
        return new User(id, "John Doe", "john.doe@example.com");
    }
}

// User.java
public class User {
    private String id;
    private String name;
    private String email;

    // Constructors, Getters, and Setters
}
```

Order Service
```java
// OrderServiceApplication.java
@SpringBootApplication
@RestController
@RequestMapping("/orders")
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }

    @Autowired
    private UserClient userClient;

    @GetMapping("/{orderId}")
    public Order getOrderById(@PathVariable String orderId) {
        User user = userClient.getUserById("123");
        return new Order(orderId, "Product 1", user);
    }
}

// Order.java
public class Order {
    private String orderId;
    private String productName;
    private User user;

    // Constructors, Getters, and Setters
}

// UserClient.java
@FeignClient(name = "user-service")
public interface UserClient {
    @GetMapping("/users/{id}")
    User getUserById(@PathVariable String id);
}
```

Configuration (Feign Client in Order Service)
```yaml
feign:
  hystrix:
    enabled: true
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
```

Explanation:

  • The `UserService` provides an endpoint `/users/{id}` to get user details.
  • The `OrderService` calls the `UserService` using a Feign client to fetch user details based on the user ID and includes this information in the order response.

Asynchronous Communication Example

  • Service A (User Service):
    • Publishes user creation events.
  • Service B (Order Service):
    • Listens to user creation events and processes them.

User Service
```java
// UserServiceApplication.java
@SpringBootApplication
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostMapping("/users")
    public void createUser(@RequestBody User user) {
        // Logic to create user
        rabbitTemplate.convertAndSend("userExchange", "user.created", user);
    }
}
```

Order Service
```java
// OrderServiceApplication.java
@SpringBootApplication
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }

    @RabbitListener(queues = "userQueue")
    public void handleUserCreated(User user) {
        // Logic to handle user creation event
    }
}

// RabbitConfig.java
@Configuration
public class RabbitConfig {

    @Bean
    public TopicExchange userExchange() {
        return new TopicExchange("userExchange");
    }

    @Bean
    public Queue userQueue() {
        return new Queue("userQueue");
    }

    @Bean
    public Binding bindingUserQueue(TopicExchange userExchange, Queue userQueue) {
        return BindingBuilder.bind(userQueue).to(userExchange).with("user.created");
    }
}
```

Explanation:

  • The `UserService` publishes a user creation event to the `userExchange`.
  • The `OrderService` listens to the `userQueue` for user creation events and processes them asynchronously.