Contrast an inbound gateway with an outbound gateway using HTTP as the example, and explain why HTTP is usually modeled as a gateway rather than a channel adapter.
answer
- Gateway = request + reply; adapter = one-way
- Inbound HTTP gateway = server: request→flow→HTTP response
- Outbound HTTP gateway = client: message→HTTP call→reply message
- HttpRequestHandlingMessagingGateway vs HttpRequestExecutingMessageHandler
- One-way HTTP adapter throws the response away
basics
~20 sHTTP is request-reply, so it maps to gateways. An inbound HTTP gateway (HttpRequestHandlingMessagingGateway) receives an HTTP request, runs the flow, and writes the reply as the HTTP response. An outbound HTTP gateway (HttpRequestExecutingMessageHandler) calls a remote HTTP endpoint and puts the response back on the flow.
solid answer
~40 sA gateway is the two-way endpoint: it both receives a request and returns a reply. Inbound vs outbound is about which side initiates. An inbound HTTP gateway (`HttpRequestHandlingMessagingGateway`, exposed via the HTTP inbound-gateway) accepts an incoming HTTP request, converts it to a Message, sends it into the flow, waits for the reply Message, and serializes that as the HTTP response — it is a server endpoint. An outbound HTTP gateway (`HttpRequestExecutingMessageHandler`) takes a Message from the flow, performs an HTTP call to a remote server, and emits the response as a reply Message back into the flow — it is a client. HTTP is inherently synchronous request-reply, so a one-way channel adapter would throw the response away; you only use the HTTP outbound *adapter* for genuine fire-and-forget where the response is irrelevant.
code
java · 22 lines@Bean
public IntegrationFlow inboundHttp() {
// SERVER: receives HTTP request, returns the flow's reply as the HTTP response
return IntegrationFlow
.from(Http.inboundGateway("/api/quote")
.requestMapping(m -> m.methods(HttpMethod.POST))
.requestPayloadType(QuoteRequest.class)
.replyTimeout(3000))
.handle("quoteService", "quote") // its return becomes the HTTP 200 body
.get();
}
@Bean
public IntegrationFlow outboundHttp() {
// CLIENT: calls a remote HTTP endpoint, puts the response back on the flow
return IntegrationFlow.from("ratesRequest")
.handle(Http.outboundGateway("https://rates.example.com/v1/rate")
.httpMethod(HttpMethod.POST)
.expectedResponseType(Rate.class)) // reply payload = Rate
.channel("ratesReply")
.get();
}go deeper
Knows a gateway is two-way and HTTP has requests and responses.
Distinguishes inbound (server) vs outbound (client) gateways and names the HTTP handler classes.
Must explain why HTTP maps to gateways not adapters, the reply/timeout/error-channel mechanics, and when the one-way adapter is still appropriate.
Generalizes the adapter-vs-gateway decision across HTTP/JMS/TCP, reasons about synchronous-blocking vs reactive HTTP, backpressure, and error-to-response contracts at API boundaries.
**Gateway = request-reply endpoint.** Where a channel adapter is one-way, a **gateway** is two-way. Two orthogonal axes describe it: **direction** (inbound = data enters the flow from outside; outbound = flow reaches out) and **initiator** (who starts the exchange). A gateway always has *both* a request path and a reply path. **Inbound HTTP gateway (server side).** Backed by `HttpRequestHandlingMessagingGateway` (the DSL `Http.inboundGateway(...)`). An external client makes an HTTP request; the gateway maps method, headers, and body to a `Message` (payload from the body via `HttpMessageConverter`s, plus `MessageHeaders` for HTTP headers/URI variables), sends it to a **request channel**, then **waits** for a reply Message and writes it back as the HTTP **response** (status, headers, body). Because it returns a response to the caller, it is a *gateway*, not an adapter. Contrast `Http.inboundChannelAdapter(...)` (`HttpRequestHandlingController`/one-way), which acknowledges with a fixed status and does *not* send a business reply — used when the HTTP call is fire-and-forget (e.g. a webhook you 200-ack immediately). **Outbound HTTP gateway (client side).** Backed by `HttpRequestExecutingMessageHandler` (DSL `Http.outboundGateway(url)`), which uses a `RestTemplate`/`RestClient` under the hood. It consumes a Message, issues the HTTP request to the remote URL (method, body, headers derived from the message/expressions), receives the HTTP response, and produces a **reply Message** (payload = response body, headers = response headers/status) back onto the flow. Its one-way sibling is `HttpRequestExecutingMessageHandler` used as an outbound *adapter* — same call, but the response is discarded because the flow doesn't need it. **Why HTTP ⇒ gateway.** HTTP's semantics are inherently synchronous request/response: every request yields a status and (usually) a body. If you modeled the client side as a one-way **outbound channel adapter**, the framework would drop the HTTP response — you'd lose status codes and payloads, unable to detect 4xx/5xx meaningfully at the flow level. If you modeled the server side as a one-way **inbound channel adapter**, you couldn't return a computed response body, only a canned ack. So the natural mapping is *gateway on both ends*, reserving the adapter form for true fire-and-forget. **Reply/timeout mechanics.** Inbound gateways have a `replyTimeout`: if the flow doesn't produce a reply in time, the gateway returns a timeout/no-content response. Outbound gateways carry the transport's own timeouts (connect/read on the `RestTemplate`/`ClientHttpRequestFactory`) plus optional `expectedResponseType`/`extractPayload`. For inbound, `errorChannel`/error handling lets you convert downstream exceptions into an HTTP error response instead of a raw 500. **Same pattern, other transports.** JMS: `JmsInboundGateway` (consumes a request from a queue with a `JMSReplyTo`, sends the reply back) vs `JmsOutboundGateway` (sends a request and correlates the reply, using a reply queue and `JMSCorrelationID`). TCP: `TcpInboundGateway` / `TcpOutboundGateway`. The inbound-vs-outbound and gateway-vs-adapter reasoning is identical across transports — HTTP is just the most intuitive example because its request-reply nature is obvious. **When to use adapter vs gateway.** - Inbound gateway: you must return a computed response to the caller (REST endpoint driven by a flow). - Inbound adapter: you only need to accept-and-ack (webhook ingestion, one-way notification). - Outbound gateway: you need the remote system's response back in the flow (enrich, branch on status). - Outbound adapter: fire-and-forget notification where the response is genuinely irrelevant.
- What breaks if you use an HTTP outbound channel adapter (one-way) instead of an outbound gateway?The HTTP call still happens, but the response — status code and body — is discarded and never returned to the flow. You can't enrich from or branch on the remote response, and you lose visibility into 4xx/5xx beyond a thrown exception. Use the gateway when the response matters.
- How is the reply routed back on an inbound HTTP gateway?The gateway sets a temporary reply channel on the request message (like @MessagingGateway). The flow's terminating handler replies to it; the gateway serializes that reply Message into the HTTP response. If no reply arrives within replyTimeout, it returns a timeout response.
- Give the JMS equivalents of inbound and outbound gateways.JmsInboundGateway consumes a request message (honoring JMSReplyTo) and sends the reply back to that destination; JmsOutboundGateway sends a request to a queue and correlates the reply (via a reply queue and JMSCorrelationID).
saying these in an interview costs you the question
- Calling HTTP endpoints 'adapters' and expecting to still read the response
- Confusing inbound (server) with outbound (client) direction
- Thinking an inbound adapter can return a computed HTTP body
- Assuming the inbound gateway never times out waiting for a reply