<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mazen Aly</title>
    <description>The latest articles on DEV Community by Mazen Aly (@mazenaly256).</description>
    <link>https://dev.to/mazenaly256</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3951938%2F197107da-8d37-4fb6-9f1a-5c8029f96024.png</url>
      <title>DEV Community: Mazen Aly</title>
      <link>https://dev.to/mazenaly256</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mazenaly256"/>
    <language>en</language>
    <item>
      <title>LINTelligent — AI-Integrated service for code linting and reviewing with MCP server</title>
      <dc:creator>Mazen Aly</dc:creator>
      <pubDate>Mon, 20 Jul 2026 07:17:07 +0000</pubDate>
      <link>https://dev.to/mazenaly256/lintelligent-ai-integrated-service-for-code-linting-with-mcp-server-4ke4</link>
      <guid>https://dev.to/mazenaly256/lintelligent-ai-integrated-service-for-code-linting-with-mcp-server-4ke4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This is a post I need to share with you my thought process, decisions that I took in designing the service, and share new things that I learned. I hope anyone can benefit from my words or inspire anyone with my ideas and what I learned so we both can grow. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mazenaly256" rel="noopener noreferrer"&gt;
        mazenaly256
      &lt;/a&gt; / &lt;a href="https://github.com/mazenaly256/LINTelligent" rel="noopener noreferrer"&gt;
        LINTelligent
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      AI-integrated backend service for code linting (i.e. analyzing code for issues), with an accompanying MCP server for AI-agent integration.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;LINTelligent&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;AI-integrated backend service for code linting (i.e. analyzing code for issues), with an accompanying &lt;strong&gt;MCP server&lt;/strong&gt; for AI-agent integration.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/mazenaly256/LINTelligent/actions/workflows/ci-pipeline.yml/badge.svg"&gt;&lt;img src="https://github.com/mazenaly256/LINTelligent/actions/workflows/ci-pipeline.yml/badge.svg" alt="CI Pipeline Building and Testing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;A code snippet is submitted in a linting/reviewing request, either as a direct snippet in the request body or via a public GitHub file URL.&lt;/p&gt;
&lt;p&gt;Once the linting request reaches the system, &lt;em&gt;LINTelligent&lt;/em&gt; saves its details in the database and enqueues a background job to the job queue for handling this request, then immediately returns 202 Accepted. If a GitHub URL was provided, the code is first fetched, then the review job runs, otherwise the review job runs directly on the submitted code snippet.&lt;/p&gt;
&lt;p&gt;After that, a worker picks up the job from the job queue and processes it, it fetches the code from the GitHub URL (if exists) then it calls the configured LLM provider with the request details and receive the review report of issues, then updates…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mazenaly256/LINTelligent" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Fun Fact:&lt;/strong&gt; While I was testing it and request reviews on some code snippets from my previous project (Cinema Seat Reservation System), LINTelligent helped me discover a critical bug related to resource wasting as I did not dispose some objects that results in memory leak.&lt;/p&gt;




&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;LINTelligent is a service that takes a code snippet as an input, and analyze it and return the issues in this code snippet.&lt;/p&gt;

&lt;p&gt;User can either use it directly by requesting the API endpoints, or via an AI agent through the MCP server.&lt;/p&gt;

&lt;h3&gt;
  
  
  The workflow
&lt;/h3&gt;

&lt;p&gt;User sends a review request, the service stores a new review with the code snippet in the database with status 'Pending', then it stores in the queue the methods that should be called to process this job/request with the related arguments for this request, then the service immediately returns 202 Accepted HTTP response so the client do not wait too much, &lt;strong&gt;detaching the client from long-running background processing&lt;/strong&gt;.&lt;br&gt;
As the jobs are saved in the queue, a worker thread picks up a job of a review request from the queue and process it, calling the methods that are stored in database as the processing way for this job. The worker sends the review request with the &lt;strong&gt;system prompt&lt;/strong&gt; and the code snippet (user message) to the LLM and receives the response, then the service persists the review report that LLM returned into the database, then it notifies the user that the the request processing has been finished.&lt;/p&gt;


&lt;h2&gt;
  
  
  System Architecture and Design
&lt;/h2&gt;

&lt;p&gt;Lets start with a basic system architecture diagram with the data flow for the service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkbjf6w5rsutk4dswkcee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkbjf6w5rsutk4dswkcee.png" alt="Basic System Architecture Diagram" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Asynchronous Processing
&lt;/h3&gt;

&lt;p&gt;I designed this system to handle the requests in an asynchronous way, so the requests are processed in the background and then the user gets notified on completion via webhook. To achieve this I used &lt;strong&gt;message/job queue pattern&lt;/strong&gt;, as shown in the diagram, the service stores the review request as a job in the job queue, and then a worker execute that job by calling the LLM, getting the review report then notify the user via webhook.&lt;/p&gt;
&lt;h4&gt;
  
  
  Queue Pattern
&lt;/h4&gt;

&lt;p&gt;The queue pattern is simply a pattern where a &lt;strong&gt;producer&lt;/strong&gt; puts messages/jobs in a &lt;strong&gt;queue&lt;/strong&gt;, and then a consumer/worker (that can be either on another machine or just another thread) that reads that job/message and executes some logic to process them.&lt;/p&gt;

&lt;p&gt;In our case, the &lt;strong&gt;producer is obviously the service&lt;/strong&gt;. Inside the endpoint of requesting a new review, it stores a job in a queue.&lt;/p&gt;

&lt;p&gt;Now we need a queue that persists the jobs/messages so the workers can take and process them one by one. Also, we need the workers themselves.&lt;/p&gt;
&lt;h4&gt;
  
  
  Hangfire Decision
&lt;/h4&gt;

&lt;p&gt;Hangfire is a technology that provides the queue and persist the jobs data in a database (stores the details about the method that is required to be called to process some logic).&lt;/p&gt;

&lt;p&gt;Also Hangfire reserves a number of threads form the thread pool of the application to create the workers pool, these are threads that only execute the enqueued jobs, each worker polls for jobs from the database and when there is a job it directly execute it.&lt;/p&gt;

&lt;p&gt;Because of that, I favored using Hangfire to implement this pattern. It is simpler and provide all-in-one solution for me and at my scale I believe that it is more than sufficient.&lt;/p&gt;

&lt;p&gt;Other choices would be more complicated and will not pay off at my scale. I could implement this using a separate queue on another server via technologies like &lt;strong&gt;RabbitMQ&lt;/strong&gt; or any similar message brokers but this will require having separate workers also that will listen to the messages or poll for them and implement the logic.&lt;/p&gt;


&lt;h3&gt;
  
  
  Handling User-Supplied URLs Safely (SSRF Mitigation)
&lt;/h3&gt;

&lt;p&gt;When I added the ability to submit a GitHub file URL instead of pasting code directly, I ran into a security problem that's easy to miss: SSRF, or Server-Side Request Forgery.&lt;/p&gt;

&lt;p&gt;The naive version of this feature is simple, take the URL the user gives you, and have your server fetch it. The problem is that "your server fetches it" part. The request doesn't come from the user's browser, it comes from your backend, using your backend's network position. If you don't restrict what URLs are allowed, an attacker isn't limited to real GitHub files, they can point your server at internal services, cloud metadata endpoints, or anything else your server can reach that the hackers normally couldn't.&lt;/p&gt;

&lt;p&gt;So a URL field isn't just an input validation problem, it's a "what is my server willing to do on someone else's behalf" problem.&lt;/p&gt;

&lt;p&gt;For handling this, I enforced exact host match on &lt;code&gt;raw.githubusercontent.com&lt;/code&gt;, and prevented any redirections when requesting the submitted URL.&lt;/p&gt;


&lt;h3&gt;
  
  
  Integration with LLM and controlling the usage cost
&lt;/h3&gt;

&lt;p&gt;When you call the LLM to integrate it in your system, you don't just send the code. You send two things every single call:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. System Prompt&lt;/strong&gt;&lt;br&gt;
This is your instructions to the LLM, it never changes between calls. It tells the LLM who it is (the persona) and what to do. It is something like:&lt;br&gt;
"You are a code review assistant. Analyze the code you receive and return ONLY a JSON object with an issues array. Each issue must have: line number, severity (error/warning/info), type, and message. Never explain yourself. Never add text outside the JSON."&lt;br&gt;
This is how you force structured output, short and structured JSON and nothing else. Without it, the AI would respond in plain English like a human, and this is hard to process in the code also it makes your output tokens explode and thereby your cost.&lt;/p&gt;

&lt;p&gt;That's exactly why the system prompt exists, to say "return JSON only, no explanations", it's not just about structure, it's also cost control. Furthermore, you handle edge cases through the system prompt, like telling the LLM that if the inferred language of the code snippet does not match the language field that is sent with the request, then return language mismatch, instead the LLM returns many compilation errors as the language is different, which is unnecessary cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. User Message&lt;/strong&gt;&lt;br&gt;
This is the actual code the user submitted, and LLM deals with it according to the instructions in the system prompt. This changes every call according to the request data, this is the "What to handle". System prompt is the "How to handle".&lt;/p&gt;


&lt;h3&gt;
  
  
  Software Design (Architecture and Patterns)
&lt;/h3&gt;

&lt;p&gt;I was building my application without caring about this at the beginning, but when I needed to perform &lt;strong&gt;Unit Testing&lt;/strong&gt;, I realized that my code is tightly coupled and needs refactoring. So, in the next sections I will specify what did I design and build exactly.&lt;/p&gt;
&lt;h4&gt;
  
  
  Clean Architecture
&lt;/h4&gt;

&lt;p&gt;When thinking in this project, it appears that it aligns well with the Clean Architecture. It has external dependencies like database, LLM, webhook notifying and GitHub integration, so they should be isolated in &lt;strong&gt;Infrastructure Layer&lt;/strong&gt;. Inside this layer, I designed it to contain implementations for LLM clients that their job is only to communicate with LLM providers and it absolutely never do anything related to the business logic, and to contain implementations for repositories. Then I built an &lt;strong&gt;Application Layer&lt;/strong&gt; that orchestrate the business workflow and decisions, so it talks to the infrastructure layer without being dependent on it, achieving loose coupling between layers.&lt;/p&gt;

&lt;p&gt;This aligns with the &lt;strong&gt;Single Responsibility Principle&lt;/strong&gt;. Also, it makes the codebase more &lt;strong&gt;testable&lt;/strong&gt; as it isolates the client and make all the business workflow orchestration only inside the Application Layer. Now if I want to write unit tests, I will never care about the client as it is simply integration details, no need to consider them in unit testing.&lt;/p&gt;
&lt;h4&gt;
  
  
  Adapter design pattern
&lt;/h4&gt;

&lt;p&gt;Appears in LLM client. It adapts the different responses of different LLMs, and give standard response to the Application Layer. So, the client itself adapts the internal shape of data to be compatible with the standard DTO defined inside the Application Layer.&lt;/p&gt;
&lt;h4&gt;
  
  
  Repository Design Pattern
&lt;/h4&gt;

&lt;p&gt;Generally, having repository pattern with EF Core is actually a bad practice. The truth is EF Core itself applies repository pattern and unit of work pattern. So if you tried to implement repository pattern, it will be just wrapper methods over the EF Core, and it will hide the power of using EF Core directly and controlling the queries and commands via LINQ.&lt;/p&gt;

&lt;p&gt;But in my case, I decided to have a repository pattern, actually I felt that it is important. In my case I just need some operations like: changing status, saving review result in the database or get review by ID. I did not need to delete anything or to generally update the records, I just needed to update specific fields and add new or get by ID, so in my case I found that it is better to have this layer that will introduce to me better API to use inside the application layer and fits better to my needs. Furthermore, the repository pattern here to achieve more loose coupling, and higher testability by using the interfaces and mocking, so it is a trade-off.&lt;/p&gt;


&lt;h2&gt;
  
  
  Integrating with the AI Agent
&lt;/h2&gt;

&lt;p&gt;I wanted to explore what it means to make a service agent-ready, not just API-ready. I wanted to make the AI agent to become another consumer of the API, so not only frontend clients can use my service via APIs, also the AI agents via &lt;strong&gt;MCP Server&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is MCP Server
&lt;/h3&gt;

&lt;p&gt;AI Agent (more accurately, Host) contains two relevant pieces: the LLM (that is responsible for the reasoning) and the Client (that communicates with MCP servers).&lt;/p&gt;

&lt;p&gt;The MCP server is essentially a layer for AI agents to use the API. REST API endpoints are great for developers building frontends that consume the API directly, but if you want AI agents to call your API endpoints, then you need this extra layer, the MCP server, communicating with AI agent either over stdio or HTTP, depending on whether it runs locally on the same machine as the agent, or the server is deployed online.&lt;/p&gt;
&lt;h4&gt;
  
  
  Docker Image
&lt;/h4&gt;

&lt;p&gt;Docker image of the local MCP server is available in the packages section in the repository.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mazenaly256" rel="noopener noreferrer"&gt;
        mazenaly256
      &lt;/a&gt; / &lt;a href="https://github.com/mazenaly256/LINTelligent" rel="noopener noreferrer"&gt;
        LINTelligent
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      AI-integrated backend service for code linting (i.e. analyzing code for issues), with an accompanying MCP server for AI-agent integration.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;LINTelligent&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;AI-integrated backend service for code linting (i.e. analyzing code for issues), with an accompanying &lt;strong&gt;MCP server&lt;/strong&gt; for AI-agent integration.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/mazenaly256/LINTelligent/actions/workflows/ci-pipeline.yml/badge.svg"&gt;&lt;img src="https://github.com/mazenaly256/LINTelligent/actions/workflows/ci-pipeline.yml/badge.svg" alt="CI Pipeline Building and Testing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;A code snippet is submitted in a linting/reviewing request, either as a direct snippet in the request body or via a public GitHub file URL.&lt;/p&gt;
&lt;p&gt;Once the linting request reaches the system, &lt;em&gt;LINTelligent&lt;/em&gt; saves its details in the database and enqueues a background job to the job queue for handling this request, then immediately returns 202 Accepted. If a GitHub URL was provided, the code is first fetched, then the review job runs, otherwise the review job runs directly on the submitted code snippet.&lt;/p&gt;
&lt;p&gt;After that, a worker picks up the job from the job queue and processes it, it fetches the code from the GitHub URL (if exists) then it calls the configured LLM provider with the request details and receive the review report of issues, then updates…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mazenaly256/LINTelligent" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Communication between AI Agent and MCP Server
&lt;/h3&gt;

&lt;p&gt;AI agent (especially the Client) does the MCP handshake via 'initialize' request to get more info about the MCP server and its capabilities then it sends 'tools/list' to know each server's tools, and the same with prompts with 'prompts/list' and resources with 'resources/list' so agent can can invoke those things when it needs. All happening at connection startup, before any actual request for any specific resource, prompt or tool. The actual request happens after that, when LLM decides to use any thing from these available tools during the reasoning loops.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;One of the things I learned in this project is what loose coupling really means in practice, I started with a tightly-coupled codebase in the beginning then I had to refactor the whole codebase and architecture to make it testable and write good unit tests.&lt;/p&gt;

&lt;p&gt;I learned many things from this project and shared with you some of them, I hope anyone can learn anything from this blog post or even take a glimpse on something new that can explore more deeply.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>backend</category>
      <category>api</category>
    </item>
    <item>
      <title>Cinema Seat Reservation System — Part 3: Problems, Decisions and Some Areas Of Improvement</title>
      <dc:creator>Mazen Aly</dc:creator>
      <pubDate>Tue, 14 Jul 2026 09:11:09 +0000</pubDate>
      <link>https://dev.to/mazenaly256/cinema-seat-reservation-system-part-3-problems-decisions-and-some-areas-of-improvement-1n65</link>
      <guid>https://dev.to/mazenaly256/cinema-seat-reservation-system-part-3-problems-decisions-and-some-areas-of-improvement-1n65</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the two previous parts, I finished sharing my main checkpoints while I was building the system till I deployed it. Today, I need to share two interesting problems that faced me and how I took decisions to solve them. I hope someone can benefit from them.&lt;br&gt;
Also, I will mention the areas of improvement in the system, how it can be better and considering their negative consequences on the system. &lt;em&gt;System design is all about Trade-offs&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can find more decisions regarding the system in &lt;code&gt;/docs/decisions/&lt;/code&gt; folder on GitHub repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mazenaly256" rel="noopener noreferrer"&gt;
        mazenaly256
      &lt;/a&gt; / &lt;a href="https://github.com/mazenaly256/Cinema-Seat-Reservation-System" rel="noopener noreferrer"&gt;
        Cinema-Seat-Reservation-System
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Cloud-native microservices-based cinema seat reservation system developed. Designed for modularity and scalability.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Cinema Seat Reservation System&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;A cloud-native, microservices-based ecosystem developed in ASP.NET Core with REST APIs. This system features deliberate design decisions optimized for modularity, scalability and resilience — implementing proven distributed systems patterns such as Retries and Circuit Breakers and Request Timeouts alongside automated CI pipelines and manual deployment workflow.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/mazenaly256/Cinema-Seat-Reservation-System/actions/workflows/api-gateway-ci-pipeline.yml/badge.svg"&gt;&lt;img src="https://github.com/mazenaly256/Cinema-Seat-Reservation-System/actions/workflows/api-gateway-ci-pipeline.yml/badge.svg" alt="CI — API Gateway"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/mazenaly256/Cinema-Seat-Reservation-System/actions/workflows/movie-service-ci-pipeline.yml/badge.svg"&gt;&lt;img src="https://github.com/mazenaly256/Cinema-Seat-Reservation-System/actions/workflows/movie-service-ci-pipeline.yml/badge.svg" alt="CI — Movie Service"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/mazenaly256/Cinema-Seat-Reservation-System/actions/workflows/reservation-service-ci-pipeline.yml/badge.svg"&gt;&lt;img src="https://github.com/mazenaly256/Cinema-Seat-Reservation-System/actions/workflows/reservation-service-ci-pipeline.yml/badge.svg" alt="CI — Reservation Service"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/mazenaly256/Cinema-Seat-Reservation-System/actions/workflows/identity-service-ci-pipeline.yml/badge.svg"&gt;&lt;img src="https://github.com/mazenaly256/Cinema-Seat-Reservation-System/actions/workflows/identity-service-ci-pipeline.yml/badge.svg" alt="CI — Identity Service"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Architectural Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Diagram&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/mazenaly256/Cinema-Seat-Reservation-System/docs/system-architecture-diagram.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmazenaly256%2FCinema-Seat-Reservation-System%2FHEAD%2Fdocs%2Fsystem-architecture-diagram.png" alt="System Architecture Diagram"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Services&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Gateway&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Centralized authentication, rate limiting, request timeouts, and routing to the main services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Identity Service&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Centralized Identity Provider — user management and JWT issuance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Movie Service&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Movies and showtimes management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reservation Service&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Seat layout, seat holds, and seat reservations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;The system is live and ready to test via &lt;strong&gt;&lt;a href="https://www.postman.com/mazenaly256-3830648/workspace/cinema-seat-reservation-system-api-documentation" rel="nofollow noopener noreferrer"&gt;Postman Workspace&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The workspace includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Complete API documentation, with organized request collections and folders for each service&lt;/li&gt;
&lt;li&gt;All API endpoints with example requests and responses, featuring interactive testing&lt;/li&gt;
&lt;li&gt;Pre-configured variables containing hosting Azure VM IP with ports to access the services&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How to…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mazenaly256/Cinema-Seat-Reservation-System" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;/h2&gt;

&lt;h2&gt;
  
  
  Problems
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Latency Problem
&lt;/h3&gt;

&lt;p&gt;One of the bottlenecks that appeared through load-testing, is that the latency of a specific endpoint (Get all showtimes with filters) takes the latency was around 850ms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Availability Problem
&lt;/h3&gt;

&lt;p&gt;Availability is simply the ability of the system to be alive and respond to requests, and do not completely die.&lt;/p&gt;

&lt;p&gt;Another problem appeared when I tried to stress test the system, I simulated huge traffic on the system and it was across the critical path in the system (that is the longest trip for a request across the services).&lt;br&gt;
Due to the large traffic the service took long time to respond, and also under stress testing the service crashed, due to exceeding the memory that limit that I determined for the container.&lt;/p&gt;

&lt;h2&gt;
  
  
  Furthermore, from a user experience perspective, a service that returns a quick, graceful error is far better than one that hangs indefinitely. Under stress testing, &lt;strong&gt;the P95 latency reached a painful 16 seconds&lt;/strong&gt;, a frustrating experience where users are highly likely to lose patience and abandon their requests entirely.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Decisions To Solve The Problems
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Solution of Latency Problem
&lt;/h3&gt;

&lt;p&gt;I accepted the idea that the latency has to be slightly high, due to the network overhead that caused by having the database and service running on different servers in different countries so there is a long trip for data over the network between the service and database, but the 850ms latency is also very high even if we consider the network delay, there must be a problem with my system design.&lt;/p&gt;

&lt;p&gt;At first glance, since the problem was related to database reading operations (data retrieval), then database indexing and caching are obvious answers to improve performance and reduce latency, but guess what? Neither of them was the solution in my case.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why indexing did not reduce the latency:
&lt;/h4&gt;

&lt;p&gt;Generally, indexing is a go-to solution in cases like this and I already created a database index on the table, but guess what? There was not any reduction in latency.&lt;br&gt;
What I learned is that due to the high latency, and the  relatively small number of rows (which is ~10,000 rows), the impact of indexing on the latency is invisible especially since the network delay itself was already massive.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why caching is not a solution (common problems in both distributed and in memory):
&lt;/h4&gt;

&lt;p&gt;Actually, I found caching would make things much worse, there are many cons for caching my situation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Range-based queries (from and to date filters) produce highly variable cache keys as if data of 2 days is requested then data of five days that span those two days is requested again, then actually we absolutely need to hit database again as we do not know if there are showtimes in those excess 3 days or not, cache usage rate would be low.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also full-list caching becomes impractical as the dataset grows to 100k+ rows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cache invalidation on create/update/delete for the domain resources adds complexity that it actually does not pay off.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are problems in both in-memory and distributed caching, but even each one has specific cons.&lt;/p&gt;

&lt;p&gt;the main problem with the in-memory caching is in a multi-containered deployment, each container instance maintains its own isolated cache, this produces inconsistent responses, as each container will have its own data separately — unacceptable for a booking system. Furthermore, syncing all those data will add significant complexity.&lt;/p&gt;

&lt;p&gt;also in my case distributed caching (via Redis or any similar) will introduce its own network overhead to transfer data between the service and the Redis instance, that introduce more network delay that will increase latency.&lt;/p&gt;

&lt;h4&gt;
  
  
  The real solution, eliminating unbounded query results
&lt;/h4&gt;

&lt;p&gt;It is pagination, instead of retrieving huge number of rows for a single request, return only a few number of rows like 10 or 20. Practically speaking, users never need more than them, they will see them and if they need more, they can load more and in this case they will accept waiting a few additional milliseconds to see new 10 or 20 showtimes, instead of waiting 850ms to retrieve 10,000 rows that user will never consider them all. &lt;strong&gt;This solution improved the performance reducing the P95 latency to ~515ms, and increased the throughput (the handled traffic) by ~25%&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Theoretically, there is an issue here that may require changing the pagination technique, the issue is that the database still reads every row it skips. Page 5 is fast. Page 5000 is slow. This becomes visible only when the number of becomes really huge.&lt;br&gt;
However, practically speaking, this number of rows will not requested as it require very long date window that contains this enormous number of showtimes, that is not requested in the real life.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution of the availability problem
&lt;/h3&gt;

&lt;p&gt;To solve this I applied rate limiting on the API gateway, this ensures that any traffic exceeding or limit fails at the edge, guaranteeing that only a manageable number of requests are processed within a given time window.&lt;/p&gt;

&lt;p&gt;Additionally, applying request timeouts helped as it prevented misbehaving requests that are unusually slow for some specific reason from degrading all the system as they take long time to be processed and take some resources. Now the system automatically cancels any request after 8 seconds and disconnect all the related connections and frees up all its allocated resources to be available to another incoming request to consume.&lt;/p&gt;

&lt;p&gt;And prevented the latency from exceeding 8 seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Possible Areas of Improvement
&lt;/h2&gt;

&lt;p&gt;In this section I would like to say that honestly, I do not know if these features will actually improve the system, or their effect will be minimal. For sure they will come with their overhead and trade-offs and will require a decision to determine whether they will introduce &lt;em&gt;an actual improvement&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Caching
&lt;/h3&gt;

&lt;p&gt;I discussed the caching when addressing the latency problem and I mentioned why it did not work, but caching may be useful in another part in the system specially when service is read heavy, and also with data that do not change frequently or the data that the way of querying them is consistent (that was not the case in my problem above).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Event-Driven Architecture and Message Brokers like Kafka and RabbitMQ
&lt;/h3&gt;

&lt;p&gt;At first glance, this solution clearly introduces a major architectural trade-off: &lt;strong&gt;Database Replication&lt;/strong&gt;. On the other hand, it has benefits including that no inter-service network calls are required so the system will be faster, and also no cascading failures, suppose that movie service crashed, the reservation service has all data on its database replica and can actually use and do its work (reserving seats in showtimes) without even knowing that movie service is down.&lt;br&gt;
This will reduce the synchronous HTTP calls that happen frequently between the services in cases like checking movie when adding a new showtime, or checking showtime when trying to reserve a seat. All those are synchronous calls that enforce the upstream service (service that makes a call) to wait for the downstream service (the called service) to respond. Also upstream service fails to do its job if the downstream service goes down.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Change the database location
&lt;/h3&gt;

&lt;p&gt;There are two options to achieve this.&lt;br&gt;
Option A: is to just get a nearer the server for our database. There is no architectural side effects and never presents more challenges, just host the DB on a nearer server to the deployment server of the services, this reduces the travelling distance for data thereby reduce network overhead.&lt;/p&gt;

&lt;p&gt;Option B: is hosting the database on the same machine as the services, this will be actually better in terms of performance due to eliminating the network overhead. But it will introduce its own overhead like the configuration headache and managing the DBMS on the server.&lt;br&gt;
Additionally, it comes with a trade-off, which is &lt;strong&gt;coupling the downtime of DB with the downtime of the system.&lt;/strong&gt; When the services and the database are hosted on different servers, the services can still be available and return friendly errors when the DB server can not be reached, instead of being fully down if they all are on one machine. This is a violation for the principle of &lt;em&gt;single point of failure&lt;/em&gt;, that is "eliminating cascading failures by separating concerns across different machines", but as I said above ad want you to remember: &lt;em&gt;System design is all about Trade-offs&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>redis</category>
      <category>testing</category>
      <category>architecture</category>
      <category>database</category>
    </item>
    <item>
      <title>Cinema Seat Reservation System — Part 2: Transitioning To Production-Scale and Deploying on Azure Cloud</title>
      <dc:creator>Mazen Aly</dc:creator>
      <pubDate>Wed, 24 Jun 2026 06:26:12 +0000</pubDate>
      <link>https://dev.to/mazenaly256/cinema-seat-reservation-system-from-baseline-local-development-to-live-cloud-native-production--238k</link>
      <guid>https://dev.to/mazenaly256/cinema-seat-reservation-system-from-baseline-local-development-to-live-cloud-native-production--238k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This is the second part of sharing my journey to create a microservices-based backend system, in the previous part, I introduced the system and its services.&lt;br&gt;
In this part I am going to mention the main things that happened with me from then until now.&lt;/p&gt;




&lt;h2&gt;
  
  
  Transitioning to online DBaaS platforms
&lt;/h2&gt;

&lt;p&gt;The first main thing was to transition my databases from my local device to accessible over the internet. I used &lt;strong&gt;Neon&lt;/strong&gt; and &lt;strong&gt;MongoDB Atlas&lt;/strong&gt;. Although performance-wise it is better to deploy the database on the same server that the whole system so all services can access the databases without &lt;strong&gt;network overhead&lt;/strong&gt;, This solution is better from a point, that is avoiding consuming the free VM instance that I got to host my main services, as with DBaaS platforms I will not require storage for databases or additional overhead to handle the DBMS on a free small resources-constrained VM.&lt;/p&gt;




&lt;h2&gt;
  
  
  Observability
&lt;/h2&gt;

&lt;p&gt;Observability is one of the main concerns in any system, it gives the ability for the system to expose what happens inside it without any need to guess and manually trace the code to determine where the error may happened.&lt;br&gt;
I utilized &lt;strong&gt;OpenTelemetry&lt;/strong&gt;, as I found it is most used and accepted tool to log, trace and collect metrics about the system and the traffic. Also, I loved that it is not related to specific framework, that is .NET by the way, I loved the idea that it is standalone tool.&lt;br&gt;
But logging and tracing and metrics collection will not be beneficial if we do not see it actually and can achieve &lt;strong&gt;monitoring&lt;/strong&gt; from those telemetry data, so I used &lt;strong&gt;Grafana Cloud&lt;/strong&gt; to export the telemetry data to some place that is accessible online and a tool that can generate dashboards and visualizing for the metrics (&lt;strong&gt;Prometheus&lt;/strong&gt;), and UI that can show all the telemetry data easily.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resilience
&lt;/h2&gt;

&lt;p&gt;I achieved &lt;em&gt;resilience&lt;/em&gt; in this system, by implementing Retry and Circuit-Breaker Pattern, that applies retires and mitigates the effect transient failures, so user can not know that there is actually a failure happened.&lt;br&gt;
Without it, any HTTP transient failure when calling a downstream service will lead to Internal Server Error response directly, even there is no permanent failure in the downstream service.&lt;/p&gt;




&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;Until this point, we have a system that is fully functional and have consistent docker configuration for its services via Docker Compose, and it database is already there and available.&lt;/p&gt;

&lt;p&gt;Now this is the point at which I wanted my system to be online and accessible from everywhere over the world, and really reach the goal: From Baseline Local Development &lt;strong&gt;To Live Cloud-Native Production&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For this I chose Azure Cloud Services, I had a virtual machine on Azure Cloud and installed Docker on it, also I configured the firewall so it added two ports to access my system, one for Identity Service, and the another one is for API Gateway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I did is as follows:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I created images from my actual code on my local machine, and pushed it to GitHub Container Registry.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I issued a token from GitHub to allow Docker engine that is installed on the virtual machine to actually pull and push the images (it is called Packages of type containers on GitHub) from and to my GitHub account.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I copied (via SCP) Docker Compose file with secret env variables file, from my local machine to the online Azure VM. Now the VM has Docker engine, and the ability to access any uploaded images on GitHub and pull/download them on the VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, I executed the command: &lt;code&gt;docker compose pull&lt;/code&gt; to pull images from GitHub Container Registry then &lt;code&gt;docker compose up&lt;/code&gt;  and to spin up the containers from them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Voilà! the system became live and accessible online.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And now, we have a live production-scale cloud-native application.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/mazenaly256/Cinema-Seat-Reservation-System/releases/tag/v4.0.0" rel="noopener noreferrer"&gt;See GitHub Release, Capturing Project at This Point&lt;/a&gt;
&lt;/h3&gt;




&lt;h2&gt;
  
  
  Workflow
&lt;/h2&gt;

&lt;p&gt;After I had this whole setup, my workflow became very consistent, it is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Make a change in the code, fixing a bug or enhance codebase or add a feature, then push it to GitHub, every change should be pushed to GitHub to achieve CI (continuous integration) practice in software development, that is simply the practice of merging the new code changes to the branch and then get automatically tested and checked, and this is achieved by the &lt;strong&gt;CI Pipeline&lt;/strong&gt; that I built using &lt;strong&gt;GitHub Actions&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then I directly rebuild the images so I get the latest changes on the code reflected on the new images.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I push these latest versions of images to GitHub Online Registry.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I access the VM through SSH, delete the old &lt;code&gt;docker-compose.yml&lt;/code&gt; and &lt;code&gt;.env&lt;/code&gt; files if they are modified.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rerun the docker compose commands to pull the latest images from GitHub Container Registry and spin up new containers and delete the old containers. So, CD (Continuous Deployment/Delivery) is achieved here (manual CD workflow).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, I want to say that this project made me learn many valuable skills, concepts and tools. There are many another things that not mentioned to keep things brief (you can get some of them by taking a look on GitHub Repository that is mentioned in Part 1 from this series, and view the commits history), and focus on the points that I feel that it really matters and think that readers can learn from it.&lt;/p&gt;

&lt;p&gt;Take a look on this series title, we really transitioned from &lt;em&gt;"Baseline Local Development"&lt;/em&gt; that is the MVP that runs on my machine, to &lt;em&gt;"Live Cloud-Native Production"&lt;/em&gt; that actually appeared in observability setup and deploying on Cloud and making it accessible online.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;If you have questions or feedback, drop them in the comments. I hope I can learn from or add benefit to one of you&lt;/u&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;For now, I am testing the system to determine its bottlenecks, for sure it has many areas of improvement, and things that even can be added to this project to make it better and more performant, I am going to mention some bugs and issues that faced me and how I overcame it and learned from them and some decisions that I made in the system. This what I will mention in the next part "Bugs, Decisions and Areas Of Improvement".&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>azure</category>
      <category>distributedsystems</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Cinema Seat Reservation System — Part 1: Overview &amp; Architecture</title>
      <dc:creator>Mazen Aly</dc:creator>
      <pubDate>Tue, 26 May 2026 08:11:09 +0000</pubDate>
      <link>https://dev.to/mazenaly256/cinema-seat-reservation-system-from-baseline-local-development-to-live-cloud-native-production--1d9i</link>
      <guid>https://dev.to/mazenaly256/cinema-seat-reservation-system-from-baseline-local-development-to-live-cloud-native-production--1d9i</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I am writing this series of blog posts to document what I am learning while building a project. You are welcome to criticize and guide me toward areas of improvement — or maybe, and I genuinely hope this, I can introduce you to concepts or ideas you haven’t encountered before, so we both can grow. I will focus on architectural and design concepts and the technologies that can be applied regardless of your framework and programming language of developing the application.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Repository
&lt;/h3&gt;

&lt;p&gt;There you can find more details, including ADRs (Architectural Design Records) and more extensive documentation.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mazenaly256" rel="noopener noreferrer"&gt;
        mazenaly256
      &lt;/a&gt; / &lt;a href="https://github.com/mazenaly256/Cinema-Seat-Reservation-System" rel="noopener noreferrer"&gt;
        Cinema-Seat-Reservation-System
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Cloud-native microservices-based cinema seat reservation system developed in ASP.NET with REST API, featuring deliberate system design decisions. Designed for modularity and scalability.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Cinema Seat Reservation System&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;&lt;em&gt;A cloud-native, microservices-based ecosystem developed in ASP.NET Core with REST APIs. This system features deliberate design decisions optimized for modularity, scalability and resilience — implementing proven distributed systems patterns such as Retries and Circuit Breakers and Request Timeouts alongside automated CI/CD pipelines.&lt;/em&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Architectural Overview&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Diagram&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/mazenaly256/Cinema-Seat-Reservation-System/docs/system-architecture-diagram.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmazenaly256%2FCinema-Seat-Reservation-System%2FHEAD%2Fdocs%2Fsystem-architecture-diagram.png" alt="System Architecture Diagram"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Services&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Movie Service:&lt;/strong&gt; Responsible for movies and showtimes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reservation Service:&lt;/strong&gt; Responsible for seats layout representation and seat reservation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity Service:&lt;/strong&gt; Acts as the centralized Identity Provider (IdP) for the system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Gateway:&lt;/strong&gt; Centralizes the logic of authentication and applies rate limiting, timeouts, and routing policies for all incoming traffic.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;API Documentation&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://www.postman.com/mazenaly256-3830648/workspace/cinema-seat-reservation-system-api-documentation" rel="nofollow noopener noreferrer"&gt;Postman API Workspace&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mazenaly256/Cinema-Seat-Reservation-System" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;





&lt;h2&gt;
  
  
  System Overview
&lt;/h2&gt;

&lt;p&gt;I have built a &lt;strong&gt;microservices-based&lt;/strong&gt; backend system, for handling seat reservations in a cinema, each service has its &lt;strong&gt;own database&lt;/strong&gt;. I applied many new concepts that I have learned including how to split the system and build the architecture that offers the modularity and future scalability for the application, building and securing API endpoints using JWT, implementing an &lt;strong&gt;API gateway&lt;/strong&gt; to be the single entry point for my whole system, &lt;strong&gt;building a basic CI Pipeline using GitHub Actions&lt;/strong&gt;, containerizing the services with configuring and running together via &lt;strong&gt;Docker Compose&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  Services
&lt;/h3&gt;

&lt;p&gt;&lt;u&gt;Movie Service:&lt;/u&gt; Responsible for CRUD operations on movies and showtimes, and enforces role-based access control.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Reservation Service:&lt;/u&gt; Responsible for handling seats availability checks and the logic of seats reservations and payment.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Identity Service:&lt;/u&gt; Acts as the &lt;strong&gt;centralized Identity Provider&lt;/strong&gt; for the whole system, responsible for &lt;strong&gt;storing and managing users&lt;/strong&gt; and &lt;strong&gt;issuing JWT tokens&lt;/strong&gt; that are trusted across all the system.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;API Gateway:&lt;/u&gt; The single entry point for the system, acting as an &lt;strong&gt;architectural AOP (Aspect-Oriented Programming) layer&lt;/strong&gt;. It &lt;strong&gt;centralizes cross-cutting concerns&lt;/strong&gt; like authentication, rate limiting, and request timeouts in one place instead of duplicating their logic across all the system services. In addition to the main responsibility of API Gateway that is &lt;strong&gt;forwarding the requests to downstream services&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  System Architecture
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4j4liw4f8axc0chel2mg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4j4liw4f8axc0chel2mg.png" alt="Basic System Architecture Diagram" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/mazenaly256/Cinema-Seat-Reservation-System/releases/tag/v3.0.0" rel="noopener noreferrer"&gt;GitHub Release&lt;/a&gt;
&lt;/h3&gt;




&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;What I am going to do in my next few posts, is to document the main points of transitioning this system from the &lt;strong&gt;development phase on my local machine&lt;/strong&gt; to a &lt;strong&gt;fully deployed, cloud-native, production-scale system&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>architecture</category>
      <category>backend</category>
    </item>
  </channel>
</rss>
