Menu

HTTP Topic

Advanced HTTP Concepts and Future Protocols

What You'll Learn:

  • HTTP/3 and QUIC protocol

  • WebSockets for real-time communication

  • Server-Sent Events (SSE) for push notifications

  • GraphQL as an alternative to REST

Detailed Explanation:

HTTP/3 and QUIC Protocol

QUIC (Quick UDP Internet Connections):

  • Transport layer protocol over UDP

  • Built-in encryption (TLS 1.3)

  • Reduced connection establishment latency

  • Improved multiplexing

HTTP/3 Benefits:

  • Faster connection setup

  • Better performance on lossy networks

  • Eliminates TCP head-of-line blocking

  • Connection migration support

WebSockets for Real-Time Communication

WebSocket Handshake:

# Client request
GET /ws/chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

# Server response
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

Spring WebSocket Configuration:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new ChatWebSocketHandler(), "/ws/chat")
                .setAllowedOrigins("*");
    }
}

@Component
public class ChatWebSocketHandler extends TextWebSocketHandler {
    
    private final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
    
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.add(session);
        broadcast("User joined: " + session.getId());
    }
    
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        broadcast("User " + session.getId() + ": " + payload);
    }
    
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session);
        broadcast("User left: " + session.getId());
    }
    
    private void broadcast(String message) {
        for (WebSocketSession session : sessions) {
            try {
                session.sendMessage(new TextMessage(message));
            } catch (IOException e) {
                // Handle error
            }
        }
    }
}

Server-Sent Events (SSE)

SSE Implementation:

@RestController
@RequestMapping("/api/events")
public class EventController {
    
    private final SseEmitterService emitterService;
    
    @GetMapping(path = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter streamEvents() {
        SseEmitter emitter = new SseEmitter(30_000L); // 30 seconds timeout
        
        emitterService.addEmitter(emitter);
        emitter.onCompletion(() -> emitterService.removeEmitter(emitter));
        emitter.onTimeout(() -> emitterService.removeEmitter(emitter));
        
        return emitter;
    }
    
    @PostMapping("/notify")
    public ResponseEntity<Void> sendNotification(@RequestBody Notification notification) {
        emitterService.sendEvent(notification);
        return ResponseEntity.ok().build();
    }
}

@Service
public class SseEmitterService {
    
    private final List<SseEmitter> emitters = new CopyOnWriteArrayList<>();
    
    public void addEmitter(SseEmitter emitter) {
        emitters.add(emitter);
    }
    
    public void removeEmitter(SseEmitter emitter) {
        emitters.remove(emitter);
    }
    
    public void sendEvent(Object event) {
        List<SseEmitter> deadEmitters = new ArrayList<>();
        
        emitters.forEach(emitter -> {
            try {
                emitter.send(SseEmitter.event()
                    .data(event)
                    .id(UUID.randomUUID().toString())
                    .name("notification"));
            } catch (Exception e) {
                deadEmitters.add(emitter);
            }
        });
        
        emitters.removeAll(deadEmitters);
    }
}

SSE Client Example:

const eventSource = new EventSource('/api/events/stream');

eventSource.onmessage = function(event) {
    const notification = JSON.parse(event.data);
    console.log('Received:', notification);
};

eventSource.onerror = function(event) {
    console.error('SSE error:', event);
};

GraphQL as REST Alternative

GraphQL vs REST:

  • REST: Multiple endpoints, over-fetching/under-fetching

  • GraphQL: Single endpoint, client-defined responses

Spring GraphQL Implementation:

@Controller
public class UserGraphQLController {
    
    @QueryMapping
    public User user(@Argument Long id) {
        return userService.findById(id);
    }
    
    @QueryMapping
    public List<User> users() {
        return userService.findAll();
    }
    
    @MutationMapping
    public User createUser(@Argument String name, @Argument String email) {
        User user = new User(name, email);
        return userService.create(user);
    }
    
    @SchemaMapping
    public List<Order> orders(User user) {
        return orderService.findByUserId(user.getId());
    }
}

GraphQL Schema:

type Query {
    user(id: ID!): User
    users: [User]
}

type Mutation {
    createUser(name: String!, email: String!): User
}

type User {
    id: ID!
    name: String!
    email: String!
    orders: [Order]
}

type Order {
    id: ID!
    total: Float!
    items: [OrderItem]
}

HTTP/3 Implementation

Spring Boot HTTP/3 Configuration:

# Enable HTTP/3 (experimental)
server.http3.enabled=true

# QUIC configuration
server.http3.quic.port=8443
server.http3.quic.certificate=classpath:cert.pem
server.http3.quic.private-key=classpath:key.pem

Advanced Caching with HTTP/3

Cache-Control for Modern Web:

# Modern caching strategy
Cache-Control: public, max-age=3600, stale-while-revalidate=300, stale-if-error=86400

# For immutable resources
Cache-Control: public, max-age=31536000, immutable

# For private user data
Cache-Control: private, no-cache

Performance Monitoring

HTTP/3 Metrics:

@Component
public class Http3Metrics {
    
    private final MeterRegistry meterRegistry;
    private final Counter requestCounter;
    private final Timer responseTimer;
    
    public Http3Metrics(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        this.requestCounter = Counter.builder("http.requests")
            .tag("protocol", "http3")
            .register(meterRegistry);
        this.responseTimer = Timer.builder("http.response.time")
            .tag("protocol", "http3")
            .register(meterRegistry);
    }
    
    public void recordRequest() {
        requestCounter.increment();
    }
    
    public void recordResponseTime(long duration) {
        responseTimer.record(duration, TimeUnit.MILLISECONDS);
    }
}

 

Comments (0)

No comments yet. Be the first to comment!

LecturreAI Assistant

Hello! I'm LecturreAI

What would you like to learn today?