Web Services Interview Guide
Master web services concepts with visual diagrams covering SOAP vs REST, SOA vs WOA, security, transactions, and decision-making criteria
Web Services enable application integration across platforms and languages. Understanding the differences between SOAP and REST, along with architectural patterns like SOA and WOA, is crucial for modern software development.
SOAP vs REST Comparison
graph TB
subgraph "SOAP Web Service"
A[SOAP Protocol] --> B[XML Only]
A --> C[WSDL Contract]
A --> D[WS-Security]
A --> E[ACID Transactions]
B --> B1[Verbose]
D --> D1[Enterprise Security]
E --> E1[2-Phase Commit]
end
subgraph "REST Web Service"
F[HTTP Protocol] --> G[Multiple Formats]
F --> H[No Formal Contract]
F --> I[SSL Security]
F --> J[Stateless]
G --> G1[JSON XML HTML]
I --> I1[Point-to-Point]
J --> J1[Cacheable]
end
style A fill:#FF9800
style F fill:#4CAF50
Key Points:
- Protocol: SOAP uses its own protocol, REST uses HTTP
- Data Format: SOAP only XML, REST supports JSON, XML, HTML, etc.
- Contract: SOAP has WSDL, REST has no formal contract
- Security: SOAP has WS-Security, REST uses SSL
- Performance: REST is faster, lighter, more scalable
Detailed Comparison Table
| Feature | SOAP | REST |
|---|---|---|
| Protocol | SOAP protocol over HTTP/SMTP/TCP | HTTP/HTTPS only |
| Data Format | XML only | JSON, XML, HTML, Plain Text |
| Contract | WSDL (formal contract) | No formal contract (OpenAPI optional) |
| State | Can be stateful or stateless | Stateless |
| Caching | Not cacheable | Cacheable (GET requests) |
| Security | WS-Security (enterprise-grade) | SSL/TLS (point-to-point) |
| Transactions | ACID, 2-phase commit | Limited transaction support |
| Bandwidth | More verbose (XML) | Less verbose (JSON) |
| Performance | Slower due to XML parsing | Faster, lightweight |
| Complexity | Complex, steep learning curve | Simple, easy to implement |
| Use Case | Enterprise, high security | Public APIs, mobile apps |
Code Comparison
// SOAP Web Service
@WebService(serviceName = "AccountService")
public class AccountServiceImpl {
@WebMethod
public Account getAccount(@WebParam(name = "accountId") Long id) {
// Business logic
return accountService.findById(id);
}
@WebMethod
public void createAccount(@WebParam(name = "account") Account account) {
accountService.save(account);
}
}
// SOAP Request (XML)
POST /AccountService HTTP/1.1
Content-Type: application/soap+xml
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<m:getAccount xmlns:m="http://example.com/account">
<m:accountId>123</m:accountId>
</m:getAccount>
</soap:Body>
</soap:Envelope>
// REST Web Service
@RestController
@RequestMapping("/api/accounts")
public class AccountController {
@GetMapping("/{id}")
public ResponseEntity<Account> getAccount(@PathVariable Long id) {
return accountService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public ResponseEntity<Account> createAccount(@RequestBody Account account) {
Account saved = accountService.save(account);
return ResponseEntity.status(HttpStatus.CREATED).body(saved);
}
}
// REST Request (JSON)
GET /api/accounts/123 HTTP/1.1
Accept: application/json
// REST Response
{
"id": 123,
"name": "John Doe",
"balance": 5000.00,
"status": "ACTIVE"
}
SOA vs WOA Architecture
graph TB
subgraph "SOA - Service Oriented Architecture"
A[Business Layer] --> B[Service Orchestration]
B --> C[SOAP Services]
C --> D[ESB Enterprise Service Bus]
D --> E[Backend Systems]
C --> C1[WSDL + XML]
D --> D1[Heavy Integration]
end
subgraph "WOA - Web Oriented Architecture"
F[UI Layer] --> G[REST Services]
G --> H[Lightweight Integration]
H --> I[Backend Systems]
G --> G1[JSON + HTTP]
H --> H1[Direct Access]
end
style C fill:#FF9800
style G fill:#4CAF50
Key Points:
- SOA: System-level architecture, exposes business capabilities
- WOA: Interface-level architecture, focuses on web-friendly APIs
- Integration: SOA uses ESB, WOA uses direct HTTP
- Format: SOA uses XML/WSDL, WOA uses JSON/REST
- Relationship: WOA = SOA + REST + WWW
Architecture Comparison
// SOA Implementation (SOAP-based)
@Configuration
public class SOAConfig {
@Bean
public ServletRegistrationBean<MessageDispatcherServlet>
messageDispatcherServlet(ApplicationContext context) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(context);
return new ServletRegistrationBean<>(servlet, "/ws/*");
}
@Bean
public DefaultWsdl11Definition accountServiceWsdl(XsdSchema schema) {
DefaultWsdl11Definition wsdl = new DefaultWsdl11Definition();
wsdl.setPortTypeName("AccountPort");
wsdl.setLocationUri("/ws");
wsdl.setTargetNamespace("http://example.com/account");
wsdl.setSchema(schema);
return wsdl;
}
}
// WOA Implementation (REST-based)
@Configuration
@EnableWebMvc
public class WOAConfig implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(
ContentNegotiationConfigurer configurer) {
configurer
.favorParameter(false)
.ignoreAcceptHeader(false)
.defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("json", MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Decision Criteria: SOAP vs REST
flowchart TD
A[Choose Web Service Type] --> B{Formal Contract Required?}
B -->|Yes| C[SOAP]
B -->|No| D{Enterprise Security?}
D -->|Yes| C
D -->|No| E{ACID Transactions?}
E -->|Yes| C
E -->|No| F{Multiple Data Formats?}
F -->|Yes| G[REST]
F -->|No| H{Public API?}
H -->|Yes| G
H -->|No| I{Mobile/Web Clients?}
I -->|Yes| G
I -->|No| J{Performance Critical?}
J -->|Yes| G
J -->|No| K[Evaluate Requirements]
style C fill:#FF9800
style G fill:#4CAF50
Key Points:
- Use SOAP When: Formal contract needed, enterprise security, ACID transactions
- Use REST When: Public API, mobile clients, performance critical, multiple formats
- Consider: Security requirements, transaction needs, client capabilities
- Evaluate: Bandwidth constraints, caching needs, development complexity
- Default: REST for most modern applications, SOAP for enterprise integration
Decision Questions
// Decision Framework
public class WebServiceDecisionFramework {
public enum ServiceType { SOAP, REST }
public ServiceType decideServiceType(Requirements req) {
// 1. Does service expose data or business logic?
if (req.exposesComplexBusinessLogic()) {
return ServiceType.SOAP; // SOAP better for logic
}
// 2. Formal contract required?
if (req.requiresFormalContract()) {
return ServiceType.SOAP; // WSDL provides contract
}
// 3. Multiple data formats needed?
if (req.requiresMultipleFormats()) {
return ServiceType.REST; // JSON, XML, HTML support
}
// 4. AJAX calls needed?
if (req.requiresAjaxCalls()) {
return ServiceType.REST; // XMLHttpRequest support
}
// 5. Stateful or stateless?
if (req.isStateless() && req.isCrudOperation()) {
return ServiceType.REST; // REST suited for stateless CRUD
}
// 6. Security level required?
if (req.requiresEnterpriseSecurityFeatures()) {
return ServiceType.SOAP; // WS-Security
}
// 7. Transaction support needed?
if (req.requiresAcidTransactions() ||
req.requiresTwoPhaseCommit()) {
return ServiceType.SOAP; // Better transaction support
}
// 8. Bandwidth limited?
if (req.hasLimitedBandwidth()) {
return ServiceType.REST; // Less verbose
}
// 9. Developer experience?
if (req.developersPreferSimplicity()) {
return ServiceType.REST; // Easier to implement
}
// 10. Default to REST for modern applications
return ServiceType.REST;
}
}
// Usage Example
Requirements requirements = new Requirements.Builder()
.exposesData(true)
.requiresMultipleFormats(true)
.isStateless(true)
.hasLimitedBandwidth(true)
.build();
WebServiceDecisionFramework framework = new WebServiceDecisionFramework();
ServiceType recommended = framework.decideServiceType(requirements);
// Result: REST
Security Comparison
// SOAP WS-Security Implementation
@Configuration
@EnableWs
public class WebServiceSecurityConfig extends WsConfigurerAdapter {
@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
// WS-Security interceptor
Wss4jSecurityInterceptor securityInterceptor =
new Wss4jSecurityInterceptor();
// Validate incoming requests
securityInterceptor.setValidationActions("UsernameToken");
securityInterceptor.setValidationCallbackHandler(
new SpringSecurityPasswordValidationCallbackHandler());
// Secure outgoing responses
securityInterceptor.setSecurementActions("UsernameToken");
securityInterceptor.setSecurementUsername("server");
securityInterceptor.setSecurementPassword("serverPassword");
interceptors.add(securityInterceptor);
}
}
// REST SSL/TLS Security
@Configuration
@EnableWebSecurity
public class RestSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.requiresChannel()
.anyRequest().requiresSecure() // Force HTTPS
.and()
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/**").authenticated()
.and()
.httpBasic()
.and()
.oauth2ResourceServer()
.jwt(); // JWT token validation
}
}
// REST API Key Security
@Component
public class ApiKeyAuthFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
String apiKey = request.getHeader("X-API-Key");
if (apiKey == null || !isValidApiKey(apiKey)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
filterChain.doFilter(request, response);
}
private boolean isValidApiKey(String apiKey) {
// Validate API key
return apiKeyService.validate(apiKey);
}
}
Testing Tools
// SoapUI for SOAP Testing
// Manual SOAP request
POST http://localhost:8080/ws/account
Content-Type: application/soap+xml
<?xml version="1.0"?>
<soap:Envelope>
<soap:Body>
<m:getAccount>
<m:accountId>123</m:accountId>
</m:getAccount>
</soap:Body>
</soap:Envelope>
// REST Testing with RestAssured
@Test
public void testGetAccount() {
given()
.pathParam("id", 123)
.when()
.get("/api/accounts/{id}")
.then()
.statusCode(200)
.body("id", equalTo(123))
.body("name", notNullValue());
}
// Postman/Curl for REST
curl -X GET http://localhost:8080/api/accounts/123 \
-H "Accept: application/json" \
-H "Authorization: Bearer token123"
// Spring MockMvc for REST
@Test
public void testCreateAccount() throws Exception {
mockMvc.perform(post("/api/accounts")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"name\":\"John\",\"balance\":1000}"))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.id").exists());
}
Best Practices
- Choose REST by Default: For most modern applications
- Use SOAP for Enterprise: When security and transactions are critical
- Consider Bandwidth: REST is better for mobile and limited bandwidth
- Formal Contracts: Use SOAP when WSDL contract is required
- Caching: Leverage REST caching for better performance
- Security: Use WS-Security for SOAP, OAuth2/JWT for REST
- Testing: Use appropriate tools (SoapUI for SOAP, Postman for REST)
- Documentation: Use OpenAPI/Swagger for REST APIs