System Design - rs-hash/Senior GitHub Wiki

  • R - Requirements
  • A - High level Architecture
  • D - Data Model ( Client )
  • I - API Model
  • O - Optimization / Performance

EXAMPLE - FACEBOOK NEWSFEED

1. 10% - Functional & Non functional requirements

Functional Requirements

  1. Feed that displays a list of items
  2. Feed item can include comments
  3. user post type
  4. should support infinit scroll

Non Functional Requirements

  1. Mobile friendly
  2. Offline access - No need to work offline but nice to access data
  3. a11y friendly
  4. internationalization
  5. performant
  6. napkin-math expected volume - 50,000 users on a weekly basis ( DataDog - observability toolreal time monitoring error rates, performance metrics, logs )

2. High level Architecture( 10- 15% )

Start with a simple UI design ( components, layout )

  • Header
  • create post composer
  • submit button
  • post with image, name, date
  • multiple posts..

design the component architecture - high level design

  • Server to communicate with client
  • index.js -> app entry file
  • index.js talks to the API and it returns JSON data
  • index.js sends data to controller, controller - brings in data from API - manipulating, parsing it, so it could be stored in Data Model (store)
  • Data model will send it to view layer
  • View layer will in turn send updates to controller - MVC pattern

discuss the design patterns you want to use & why

How MVC is Used in Frontend Applications:

Model:

  • The model represents the data and business logic of the application. It deals with data manipulation, validation, and storage. Models are responsible for fetching and updating data from the backend or database
  • In frontend applications, models represent data structures, API interactions, and state management. They encapsulate data and provide methods for fetching, updating, and managing data.
  • For example, in a React application, Redux or Context API can serve as the model layer to manage application state and handle data flow.

View:

  • The view represents the user interface (UI) of the application. It displays data to the user and handles user interactions such as clicks, inputs, and gestures. Views are responsible for presenting data in a visually appealing and interactive manner.
  • Views in frontend applications are responsible for rendering UI components, displaying data, and handling user interactions.
  • In frameworks like React, Vue.js, or Angular, components serve as views.They receive data from models or state management systems and render UI elements accordingly.

Controller:

  • The controller acts as an intermediary between the model and the view. It handles user inputs, processes requests, and updates the model or view accordingly. Controllers contain application logic and orchestrate the flow of data and actions.
  • In frontend applications, controllers are often replaced or complemented by routers and state management libraries.
  • Routers handle routing and navigation between different views/components based on user interactions or URL changes.
  • State management libraries (e.g., Redux, MobX, VueX) act as controllers by managing application state, handling actions, and updating views/components.

explain how the data will flow

explain how interactions will work

3. Data Model ( Client ) 20%

4. API Design

what HTTP protocol needs to be used, why ( graphql,websockets .. )

HTTP/1.1:

  • Connection Handling: HTTP/1.1 uses a request-response model where each request establishes a new TCP connection. This results in multiple connections for parallel downloads, leading to potential performance bottlenecks (head-of-line blocking).
  • Header Compression: Headers are sent in plain text for each request and response, which can increase overhead, especially for small requests.
  • Multiplexing: HTTP/1.1 lacks native support for multiplexing, meaning that only one request can be processed at a time on a single connection.
  • Resource Prioritization: It doesn't have built-in support for prioritizing resources, leading to potential inefficiencies in resource loading.
  • Performance: While HTTP/1.1 served the web well for many years, its limitations in connection handling, header compression, and multiplexing can lead to slower page load times, especially for complex web applications with many resources.

HTTP2

  • Multiplexing: HTTP/2 introduces multiplexing, allowing multiple requests and responses to be sent and received simultaneously on a single connection. This improves resource loading and reduces latency.
  • Header Compression: HTTP/2 uses header compression techniques like HPACK to reduce overhead, leading to faster communication.
  • Stream Prioritization: It introduces stream prioritization, allowing clients to specify the importance of different resources, improving overall resource loading strategies.
  • Binary Protocol: HTTP/2 uses a binary protocol instead of plain text, further reducing overhead and improving efficiency.
  • Performance: HTTP/2 significantly improves performance compared to HTTP/1.1, especially for complex web applications with many resources.

HTTP3

  • Protocol: HTTP/3 is built on top of the QUIC (Quick UDP Internet Connections - The User Datagram Protocol (UDP) is a connectionless communication protocol for transporting packets across networks) protocol instead of TCP. QUIC is designed to reduce latency and improve performance by using UDP (User Datagram Protocol) instead of TCP.
  • Multiplexing and Stream Prioritization: HTTP/3 retains the multiplexing and stream prioritization features of HTTP/2 but improves efficiency and reduces latency further due to the underlying QUIC protocol.
  • Connection Establishment: HTTP/3 allows for faster connection establishment and reduced handshake times compared to TCP-based protocols like HTTP/1.1 and HTTP/2.
  • Loss Recovery: QUIC includes built-in mechanisms for fast loss recovery and congestion control, improving reliability and robustness in challenging network conditions.
  • Performance: HTTP/3 aims to further improve performance, especially in scenarios with high latency or packet loss, by leveraging the benefits of the QUIC protocol.

CDN - Content delivery network

loadbalancer -

API MODEL - Polling - HTTP Request- REST API

  • REST API: Suitable for CRUD operations and structured data interactions.
  • GraphQL: Provides fine-grained control over data fetching and supports complex queries.
  • WebSockets: Ideal for real-time, bidirectional communication and applications requiring low-latency updates.
  • Server-Sent Events (SSE): Suitable for one-way server-to-client updates and real-time notifications without bidirectional communication needs.

REST API (Representational State Transfer):

Description:

  • REST is an architectural style for designing networked applications. RESTful APIs use standard HTTP methods (GET, POST, PUT, DELETE, etc.) to perform CRUD (Create, Read, Update, Delete) operations on resources.

Usage:

  • REST APIs are widely used for server-client communication in web applications, mobile apps, and backend services.
  • They are suitable for scenarios where clients need to access and manipulate structured data stored on a server.

Pros:

  • Simple and intuitive to understand and implement.
  • Well-suited for CRUD operations and structured data interactions.
  • Good compatibility with HTTP caching, authentication, and security mechanisms.

Cons:

  • Over-fetching or under-fetching of data can occur, leading to inefficiencies.
  • Limited flexibility in querying specific data fields or nested relationships.

GraphQL:

Description:

  • GraphQL is a query language and runtime for APIs that allows clients to request specific data fields and nested relationships in a single query. It provides a more flexible and efficient alternative to RESTful APIs.

Usage:

  • GraphQL is used in scenarios where clients require fine-grained control over the data they fetch from the server, reducing over-fetching and under-fetching.
  • It is suitable for complex data fetching requirements and scenarios where data structures evolve frequently.

Pros:

  • Clients can request exactly the data they need, reducing data transfer overhead and improving performance.
  • Supports nested queries, aliases, fragments, and introspection for advanced querying and schema exploration.
  • Facilitates versionless APIs and allows schema evolution without breaking existing clients.

Cons:

  • Requires a learning curve for both developers and server implementations.
  • May not be necessary for simple APIs or applications with straightforward data requirements.

WebSockets:

Description:

  • WebSockets is a protocol that provides full-duplex communication channels over a single TCP connection. It allows real-time, bidirectional communication between clients (such as browsers) and servers.

Usage:

  • WebSockets are used in applications requiring real-time updates, such as chat apps, live notifications, collaborative editing tools, and real-time data streaming.
  • They enable low-latency, event-driven communication without the overhead of HTTP request-response cycles.

Pros:

  • Supports real-time, bidirectional communication between clients and servers.
  • Enables server-initiated updates or notifications without the need for polling.
  • Low-latency and efficient for real-time applications.

Cons:

  • Requires server-side support for WebSockets and more load balancers to handle for connection management and scalability.
  • May not be necessary for applications that don't require real-time updates or bidirectional communication.

5. Peformance

performance in Network layer

  • Prefer HTTP 2 for better performance - supports Multiplexing
  • if we have have chats - where wec ould do hybrid approach - use websocket for chat and http2 for other calls
  • compressing the headers using header compression when you're requesting data from the server
  • modern compression - brotli, better than gzip
  • send request with these headers to let servers know what sort of compression algorithm used
  • server caching
  • Image optimization
  • Bundle splitting- lazy load
  • compress everything
  • apollo caching - caching built in graphQL
  const client = new ApolloClient({
  uri: 'https://your-graphql-endpoint', // Specify your GraphQL endpoint
  cache: new InMemoryCache(),
 });

Rendering Performance

  • Mobile friendly
  • smart caching in client
  • utilize localstorage session storage, cookie storage
  • success error & loading states
  • Server side rendering
  • Defer non critical resources
  • focus on above the fold content - focus on whats on users screen
  • calculate time to interactive - calculate first contentful paint, log when component rendered with data
  • Preload JS when needed
  • Import only what you need
  • Tree shaking, eliminate dead code
  • Virtualization
  • CSS - avoid reflows -
  • Debounce, throttle

Accesibility

  • REM font sizes
  • cross device tests
  • color contrast ratio
  • keyboard navigation
  • semantic tags - nav
  • aria roles

Securiy

  • CORS - Cross origin resource sharing - acess on a specific domain
  • Rate limiting
  • XSS - cross site scripting, inject js into your site