Unlocking Real-Time Magic: FastAPI – WebSockets to Multiple Angular Frontends
Image by Jewelle - hkhazo.biz.id

Unlocking Real-Time Magic: FastAPI – WebSockets to Multiple Angular Frontends

Posted on

Imagine a web application where multiple users can collaborate seamlessly, with each user’s actions reflected in real-time across all connected frontends. Sounds like science fiction, right? Well, today we’re going to make it a reality using FastAPI, WebSockets, and Angular. Buckle up and get ready to dive into the world of real-time web development!

Why FastAPI and WebSockets?

Before we dive into the implementation, let’s quickly discuss why we’re choosing FastAPI and WebSockets for this project.

  • FastAPI**: As a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints, FastAPI offers a lot of benefits, including automatic API documentation, support for async/await, and robust error handling.
  • WebSockets**: WebSockets provide a bi-directional, real-time communication channel between the client (Angular frontend) and the server (FastAPI backend). This allows us to push updates from the server to the client instantly, creating a seamless and interactive user experience.

Setting Up the Project

To get started, create a new FastAPI project using the following command:

fastapi create my_project

Next, create a new Angular project using the Angular CLI:

ng new my_angular_app

FastAPI Backend Implementation

Let’s start by creating a new file `main.py` in the FastAPI project directory:

from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponse

app = FastAPI()

# Store connected WebSocket clients
clients = []

@app.websocket("/ws/{client_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: str):
    await websocket.accept()
    clients.append((client_id, websocket))

    try:
        while True:
            # Receive message from client
            message = await websocket.receive_text()
            print(f"Received message from client {client_id}: {message}")

            # Broadcast message to all connected clients
            for client in clients:
                if client[0] != client_id:
                    await client[1].send_text(message)
    except:
        # Remove client from the list when the connection is closed
        clients.remove((client_id, websocket))

@app.get("/index.html")
async def read_index():
    html_content = """
    <html>
    <head></head>
    <body>
        <h1>FastAPI - WebSockets to Multiple Angular Frontends</h1>
        <script src="static/index.js"></script>
    </body>
    </html>
    """
    return HTMLResponse(content=html_content, media_type="text/html")

In this code, we’re creating a FastAPI app with a single WebSocket endpoint `/ws/{client_id}`. When a client connects to this endpoint, we store the client’s ID and WebSocket object in a list. We then listen for messages received from the client and broadcast them to all other connected clients.

Angular Frontend Implementation

Create a new file `index.js` in the Angular project directory:

import { Component, OnDestroy, OnInit } from '@angular/core';
import { NgrokTunnel } from 'ngrok-tunnel';

@Component({
  selector: 'app-root',
  template: `
    <div>
      <h1>Connected Client {{ clientId }}</h1>
      <input type="text" [(ngModel)]="message">
      <button (click)="sendMessage()">Send Message</button>
      <ul>
        <li *ngFor="let message of messages">{{ message }}</li>
      </ul>
    </div>
  `
})
export class AppComponent implements OnInit, OnDestroy {
  clientId: string;
  message: string;
  messages: string[] = [];
  ws: WebSocket;

  ngOnInit(): void {
    this.clientId = Math.random().toString(36).substr(2, 9);
    this.ws = new WebSocket('ws://localhost:8000/ws/' + this.clientId);

    this.ws.onmessage = (event) => {
      this.messages.push(event.data);
    };

    this.ws.onopen = () => {
      console.log('Connected to the WebSocket');
    };

    this.ws.onerror = (event) => {
      console.error('WebSocket error:', event);
    };

    this.ws.onclose = () => {
      console.log('WebSocket connection closed');
    };
  }

  ngOnDestroy(): void {
    this.ws.close();
  }

  sendMessage(): void {
    this.ws.send(this.message);
    this.message = '';
  }
}

In this code, we’re creating an Angular component that connects to the FastAPI WebSocket endpoint using the `WebSocket` API. We’re storing the client’s ID and WebSocket object as properties of the component. When the component is initialized, we set up event listeners for WebSocket events and send a message to the server when the user clicks the “Send Message” button.

Running the Application

To run the application, start the FastAPI server using the following command:

uvicorn main:app --reload --host 0.0.0.0 --port 8000

Next, start the Angular development server using the following command:

ng serve --open

This will launch the Angular application in your default web browser. Open multiple instances of the application to simulate multiple clients. When you send a message from one client, it should be reflected in real-time across all connected clients.

Conclusion

In this article, we’ve demonstrated how to create a real-time web application using FastAPI, WebSockets, and Angular. By leveraging the power of WebSockets, we’ve enabled multiple clients to collaborate seamlessly, with each client’s actions reflected in real-time across all connected frontends.

FastAPI’s support for async/await and robust error handling makes it an ideal choice for building real-time web applications. Angular’s robust ecosystem and simplicity make it a great choice for building complex frontends. By combining these technologies, we’ve created a powerful and scalable solution for real-time collaboration.

Future Enhancements

There are many ways to enhance this project, including:

  • Implementing authentication and authorization to restrict access to the WebSocket endpoint
  • Adding support for multiple chat rooms or channels
  • Implementing a more robust message storage system using a database
  • Adding support for file uploads and real-time file sharing

The possibilities are endless! With FastAPI, WebSockets, and Angular, the sky’s the limit for building real-time web applications.

Final Thoughts

In conclusion, we’ve demonstrated the power of FastAPI, WebSockets, and Angular in building real-time web applications. By following this tutorial, you should now have a solid understanding of how to create a real-time web application that enables multiple clients to collaborate seamlessly.

Remember, the key to building successful real-time web applications is to focus on scalability, performance, and user experience. With the right tools and technologies, the possibilities are endless!

Keyword Explanation
FastAPI A modern, fast (high-performance), web framework for building APIs with Python 3.7+
WebSockets A bi-directional, real-time communication channel between the client and server
Angular A popular JavaScript framework for building complex frontends

We hope you enjoyed this article and learned something new. Happy coding!

Frequently Asked Question

In the world of real-time web development, using FastAPI and Websockets to connect multiple Angular frontends can be a game-changer. But, how do you ensure that each frontend detects changes made by others in real-time? Let’s dive into some frequently asked questions to find out!

Q1: How do I establish a WebSocket connection between FastAPI and multiple Angular frontends?

To establish a WebSocket connection, you need to create a WebSocket endpoint in your FastAPI backend using the `WebSocketEndpoint` class. Then, in your Angular frontend, use the `ws` library to create a WebSocket connection to the FastAPI endpoint. Make sure to handle the WebSocket connection lifecycle events, such as `onopen`, `onmessage`, `onerror`, and `onclose`, to send and receive messages between the frontend and backend.

Q2: How do I broadcast changes made by one frontend to all other connected frontends in real-time?

To broadcast changes to all connected frontends, you can use a pub/sub mechanism. In FastAPI, you can use a library like `async genera` to create a publisher-subscriber system. When a frontend sends a message to the backend, the backend can publish the message to all connected frontends. Each frontend can then subscribe to the publisher to receive updates in real-time.

Q3: How do I handle concurrent updates to the same resource from multiple frontends?

To handle concurrent updates, you can implement optimistic concurrency control in your FastAPI backend. This involves checking the version or timestamp of the resource being updated and rejecting updates if the resource has been modified since the frontend last retrieved it. You can also use transactions to ensure atomicity of updates.

Q4: Can I use WebSockets to push updates to frontends even when they’re not actively requesting data?

Yes, you can! WebSockets allow for bi-directional communication between the frontend and backend, enabling the backend to push updates to the frontend even when it’s not actively requesting data. This is particularly useful for real-time applications where data needs to be updated in response to external events or changes.

Q5: How do I handle WebSocket connection errors and disconnections in my Angular frontend?

To handle WebSocket connection errors and disconnections, you can implement retry logic in your Angular frontend to reconnect to the FastAPI backend when the connection is lost. You can also use error handling mechanisms, such as try-catch blocks, to catch and handle errors that occur during WebSocket communication.

Leave a Reply

Your email address will not be published. Required fields are marked *