diff --git a/.env b/.env
index 09923e3d32fed99977efd11b929861244780c93b..673e590786e96e46a0ea58e0f4a06002a86fd218 100644
--- a/.env
+++ b/.env
@@ -1,12 +1,17 @@
 # Image settings
 IMAGE_TAG=0.0.1
+MYSQL_IMAGE_TAG=8.0
+
 
 # Database configuration
-DB_PORT=3308
-DB_NAME=AspNetCoreDb
-DB_USER=root
-DB_PASSWORD=
+DB_PORT=3307
+DB_NAME=myDB
+DB_USER=user
+DB_PASSWORD=user
 DB_CHARSET=utf8mb4
 
 # Service ports
-USER_MICROSERVICE_PORT=5089  # This port will be used as the JWT issuer
+USER_MICROSERVICE_PORT=5089
+FLIGHT_MICROSERVICE_PORT=5175
+GATEWAY_API_PORT=5267
+CLIENT_PORT=4200
\ No newline at end of file
diff --git a/Database/InitTables.sql b/Database/InitTables.sql
new file mode 100644
index 0000000000000000000000000000000000000000..6805d233e8cd62079b3e81de3c91104ab1e61098
--- /dev/null
+++ b/Database/InitTables.sql
@@ -0,0 +1,34 @@
+CREATE TABLE Users (
+    Id INT AUTO_INCREMENT PRIMARY KEY,
+    Username LONGTEXT NOT NULL,
+    Email LONGTEXT NOT NULL,
+    PasswordHash LONGTEXT NOT NULL,
+    Type INT NOT NULL
+);
+
+CREATE TABLE RefreshTokens (
+    Id INT AUTO_INCREMENT PRIMARY KEY,
+    UserId INT NOT NULL,
+    Token LONGTEXT NOT NULL,
+    ExpirationDate DATETIME(6) NOT NULL
+);
+
+CREATE TABLE Flights (
+    Id INT AUTO_INCREMENT PRIMARY KEY,
+    Origin LONGTEXT NOT NULL,
+    Destination LONGTEXT NOT NULL,
+    DepartureTime DATETIME(6) NOT NULL,
+    ArrivalTime DATETIME(6) NOT NULL,
+    EconomyCapacity INT NOT NULL,
+    BusinessCapacity INT NOT NULL,
+    EconomyPrice DECIMAL(65, 30) NOT NULL,
+    BusinessPrice DECIMAL(65, 30) NOT NULL
+);
+
+CREATE TABLE Seats (
+    Id INT AUTO_INCREMENT PRIMARY KEY,
+    FlightId INT NOT NULL,
+    SeatNumber LONGTEXT NOT NULL,
+    ClassType INT NOT NULL,
+    IsAvailable TINYINT(1) NOT NULL
+);
diff --git a/GatewayAPI/.dockerignore b/GatewayAPI/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..fe1152bdb8442f4d14f9b9533e63fe0c2680bcee
--- /dev/null
+++ b/GatewayAPI/.dockerignore
@@ -0,0 +1,30 @@
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
+!**/.gitignore
+!.git/HEAD
+!.git/config
+!.git/packed-refs
+!.git/refs/heads/**
\ No newline at end of file
diff --git a/GatewayAPI/Clients/FlightService/FlightServiceClient.cs b/GatewayAPI/Clients/FlightService/FlightServiceClient.cs
new file mode 100644
index 0000000000000000000000000000000000000000..cdf5f3a75248f64842cd7cc1bde1d9a0879f1a66
--- /dev/null
+++ b/GatewayAPI/Clients/FlightService/FlightServiceClient.cs
@@ -0,0 +1,75 @@
+using GatewayAPI.Models;
+
+namespace GatewayAPI.Clients.FlightService
+{
+    public class FlightServiceClient : IFlightServiceClient
+    {
+        private readonly HttpClient httpClient;
+        private static readonly string FLIGHT_API_PATH = "api/Flight";
+        private static readonly string SEAT_API_PATH = "api/Seat";
+
+        public FlightServiceClient(HttpClient httpClient)
+        {
+            this.httpClient = httpClient;
+        }
+
+        public async Task<HttpResponseMessage> GetFlightAsync(int flightId)
+        {
+            return await httpClient.GetAsync($"{FLIGHT_API_PATH}/{flightId}");
+        }
+
+        public async Task<HttpResponseMessage> GetFlightsAsync(string? origin = null, string? destination = null, DateTime? departureTime = null, DateTime? arrivalTime = null)
+        {
+            var queryParams = new List<string>();
+
+            if (origin != null)
+                queryParams.Add($"origin={Uri.EscapeDataString(origin)}");
+
+            if (destination != null)
+                queryParams.Add($"destination={Uri.EscapeDataString(destination)}");
+
+            if (departureTime.HasValue)
+                queryParams.Add($"departureTime={departureTime.Value.ToString("yyyy-MM-dd HH:mm:ss.fff") + "000"}");
+
+            if (arrivalTime.HasValue)
+                queryParams.Add($"arrivalTime={arrivalTime.Value.ToString("yyyy-MM-dd HH:mm:ss.fff") + "000"}");
+
+            string queryString = queryParams.Any() ? $"?{string.Join("&", queryParams)}" : string.Empty;
+
+            return await httpClient.GetAsync($"{FLIGHT_API_PATH}{queryString}");
+        }
+
+        public async Task<HttpResponseMessage> AddFlightAsync(FlightCreation flight)
+        {
+            return await httpClient.PostAsJsonAsync(FLIGHT_API_PATH, flight);
+        }
+
+        public async Task<HttpResponseMessage> GetFlightCapacityAsync(int flightId, int classType)
+        {
+            return await httpClient.GetAsync($"{FLIGHT_API_PATH}/{flightId}/capacity?ClassType={classType}");
+        }
+
+
+
+
+        public async Task<HttpResponseMessage> GetSeatsAsync()
+        {
+            return await httpClient.GetAsync(SEAT_API_PATH);
+        }
+
+        public async Task<HttpResponseMessage> GetSeatAsync(int seatId)
+        {
+            return await httpClient.GetAsync($"{SEAT_API_PATH}/{seatId}");
+        }
+
+        public async Task<HttpResponseMessage> IsSeatAvailableAsync(int seatId)
+        {
+            return await httpClient.GetAsync($"{SEAT_API_PATH}/{seatId}/isAvailable");
+        }
+
+        public async Task<HttpResponseMessage> BookSeatAsync(int seatId)
+        {
+            return await httpClient.PutAsync($"{SEAT_API_PATH}/{seatId}", null);
+        }
+    }
+}
diff --git a/GatewayAPI/Clients/FlightService/IFlightServiceClient.cs b/GatewayAPI/Clients/FlightService/IFlightServiceClient.cs
new file mode 100644
index 0000000000000000000000000000000000000000..def17a9d8dc494c5e1dd6242f36ff299e3b954a2
--- /dev/null
+++ b/GatewayAPI/Clients/FlightService/IFlightServiceClient.cs
@@ -0,0 +1,18 @@
+using GatewayAPI.Models;
+
+namespace GatewayAPI.Clients.FlightService
+{
+    public interface IFlightServiceClient
+    {
+        Task<HttpResponseMessage> GetFlightAsync(int flightId);
+        Task<HttpResponseMessage> GetFlightsAsync(string? origin = null, string? destination = null, DateTime? departureTime = null, DateTime? arrivalTime = null);
+        Task<HttpResponseMessage> AddFlightAsync(FlightCreation flight);
+        Task<HttpResponseMessage> GetFlightCapacityAsync(int flightId, int classType);
+
+
+        Task<HttpResponseMessage> GetSeatsAsync();
+        Task<HttpResponseMessage> GetSeatAsync(int seatId);
+        Task<HttpResponseMessage> IsSeatAvailableAsync(int seatId);
+        Task<HttpResponseMessage> BookSeatAsync(int seatId);
+    }
+}
diff --git a/GatewayAPI/Clients/UserService/IUserServiceClient.cs b/GatewayAPI/Clients/UserService/IUserServiceClient.cs
new file mode 100644
index 0000000000000000000000000000000000000000..dfcaeb7ba7c830d08f4d0baa639349d0a104685c
--- /dev/null
+++ b/GatewayAPI/Clients/UserService/IUserServiceClient.cs
@@ -0,0 +1,15 @@
+using GatewayAPI.Models;
+
+namespace GatewayAPI.Clients.UserService
+{
+    public interface IUserServiceClient
+    {
+        Task<HttpResponseMessage> GetUserAsync(int id);
+        Task<HttpResponseMessage> GetUsersAsync();
+        Task<HttpResponseMessage> RegisterUserAsync(UserRegistration user);
+        Task<HttpResponseMessage> LoginUserAsync(UserLogin user);
+        Task<HttpResponseMessage> AuthorizeUserAsync();
+        Task<HttpResponseMessage> LogoutUserAsync();
+        Task<HttpResponseMessage> UpdateUserAsync(int id, UserUpdateInfo updateInfo);
+    }
+}
diff --git a/GatewayAPI/Clients/UserService/UserServiceClient.cs b/GatewayAPI/Clients/UserService/UserServiceClient.cs
new file mode 100644
index 0000000000000000000000000000000000000000..46752a45606c68ef74aee88de8a42598d4d0dea4
--- /dev/null
+++ b/GatewayAPI/Clients/UserService/UserServiceClient.cs
@@ -0,0 +1,54 @@
+using GatewayAPI.Models;
+using System.Net.Http;
+using System.Net.Http.Json;
+using System.Text.Json;
+
+namespace GatewayAPI.Clients.UserService
+{
+    public class UserServiceClient : IUserServiceClient
+    {
+        private readonly HttpClient httpClient;
+        private static readonly string API_PATH = "api/User";
+
+        public UserServiceClient(HttpClient httpClient)
+        {
+            this.httpClient = httpClient;
+        }
+
+        public async Task<HttpResponseMessage> GetUserAsync(int id)
+        {
+            return await httpClient.GetAsync($"{API_PATH}/{id}");
+        }
+
+        public async Task<HttpResponseMessage> GetUsersAsync()
+        {
+            return await httpClient.GetAsync($"{API_PATH}");
+        }
+
+        public async Task<HttpResponseMessage> RegisterUserAsync(UserRegistration user)
+        {
+            return await httpClient.PostAsJsonAsync($"{API_PATH}/register", user);
+        }
+
+        public async Task<HttpResponseMessage> LoginUserAsync(UserLogin user)
+        {
+            return await httpClient.PostAsJsonAsync($"{API_PATH}/login", user);
+        }
+
+        public async Task<HttpResponseMessage> AuthorizeUserAsync()
+        {
+            return await httpClient.PostAsync($"{API_PATH}/authorize", null);
+        }
+
+        public async Task<HttpResponseMessage> LogoutUserAsync()
+        {
+            return await httpClient.PostAsync($"{API_PATH}/logout", null);
+        }
+
+        public async Task<HttpResponseMessage> UpdateUserAsync(int id, UserUpdateInfo updateInfo)
+        {
+            return await httpClient.PatchAsJsonAsync($"{API_PATH}/{id}", updateInfo);
+        }
+
+    }
+}
diff --git a/GatewayAPI/Controllers/FlightController.cs b/GatewayAPI/Controllers/FlightController.cs
new file mode 100644
index 0000000000000000000000000000000000000000..e335bd102327e36d733c4b3e59b23020fa25182a
--- /dev/null
+++ b/GatewayAPI/Controllers/FlightController.cs
@@ -0,0 +1,47 @@
+using GatewayAPI.Clients.FlightService;
+using GatewayAPI.Clients.UserService;
+using GatewayAPI.Models;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GatewayAPI.Controllers
+{
+    [ApiController]
+    [Route("api/[Controller]")]
+    public class FlightController : ControllerBase
+    {
+        private readonly IFlightServiceClient flightServiceClient;
+        public FlightController(IFlightServiceClient flightServiceClient)
+        {
+            this.flightServiceClient = flightServiceClient;
+        }
+
+        [HttpGet()]
+        public async Task<IActionResult> GetFlights(string? origin = null, string? destination = null, DateTime? departureTime = null, DateTime? arrivalTime = null)
+        {
+            HttpResponseMessage response = await flightServiceClient.GetFlightsAsync(origin, destination, departureTime, arrivalTime);
+            return new HttpResponseMessageResult(response);
+        }
+
+        [HttpGet("{id}")]
+        public async Task<IActionResult> GetFlights(int id)
+        {
+            HttpResponseMessage response = await flightServiceClient.GetFlightAsync(id);
+            return new HttpResponseMessageResult(response);
+        }
+
+        [HttpPost()]
+        public async Task<IActionResult> AddFlight([FromBody] FlightCreation flightCreation)
+        {
+            HttpResponseMessage response = await flightServiceClient.AddFlightAsync(flightCreation);
+            return new HttpResponseMessageResult(response);
+        }
+
+
+        [HttpGet("{id}/capacity")]
+        public async Task<IActionResult> GetFlightCapacity([FromRoute] int id, [FromQuery] int classType)
+        {
+            HttpResponseMessage response = await flightServiceClient.GetFlightCapacityAsync(id, classType);
+            return new HttpResponseMessageResult(response);
+        }
+    }
+}
diff --git a/GatewayAPI/Controllers/SeatController.cs b/GatewayAPI/Controllers/SeatController.cs
new file mode 100644
index 0000000000000000000000000000000000000000..750dfa67d086a9b8eded50d22a24ab1a469131be
--- /dev/null
+++ b/GatewayAPI/Controllers/SeatController.cs
@@ -0,0 +1,45 @@
+using GatewayAPI.Clients.FlightService;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GatewayAPI.Controllers
+{
+    [ApiController]
+    [Route("api/[controller]")]
+    public class SeatController : ControllerBase
+    {
+        private readonly IFlightServiceClient flightServiceClient;
+        public SeatController(IFlightServiceClient flightServiceClient)
+        {
+            this.flightServiceClient = flightServiceClient;
+        }
+
+        [HttpGet()]
+        public async Task<IActionResult> GetSeats()
+        {
+            HttpResponseMessage response = await flightServiceClient.GetSeatsAsync();
+            return new HttpResponseMessageResult(response);
+        }
+
+        [HttpGet("{id}")]
+        public async Task<IActionResult> GetSeats(int id)
+        {
+            HttpResponseMessage response = await flightServiceClient.GetSeatAsync(id);
+            return new HttpResponseMessageResult(response);
+        }
+
+        [HttpPut("{id}")]
+        public async Task<IActionResult> BookSeat(int id)
+        {
+            HttpResponseMessage response = await flightServiceClient.BookSeatAsync(id);
+            return new HttpResponseMessageResult(response);
+        }
+
+        [HttpGet("{id}/isAvailable")]
+        public async Task<IActionResult> IsAvailable(int id)
+        {
+            HttpResponseMessage response = await flightServiceClient.IsSeatAvailableAsync(id);
+            return new HttpResponseMessageResult(response);
+        }
+
+    }
+}
diff --git a/GatewayAPI/Controllers/UserController.cs b/GatewayAPI/Controllers/UserController.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2061f69c6f09c131ffce64f62e6a06a79b76513e
--- /dev/null
+++ b/GatewayAPI/Controllers/UserController.cs
@@ -0,0 +1,68 @@
+using GatewayAPI.Clients.UserService;
+using GatewayAPI.Models;
+using Microsoft.AspNetCore.Mvc;
+using System.Text;
+
+namespace GatewayAPI.Controllers
+{
+    [ApiController]
+    [Route("api/[Controller]")]
+    public class UserController : ControllerBase
+    {
+        private readonly IUserServiceClient userServiceClient;
+        public UserController(IUserServiceClient userServiceClient)
+        {
+            this.userServiceClient = userServiceClient;
+        }
+
+        [HttpPost("register")]
+        public async Task<IActionResult> Register([FromBody] UserRegistration userRegistration)
+        {
+            HttpResponseMessage response = await userServiceClient.RegisterUserAsync(userRegistration);
+            return new HttpResponseMessageResult(response);
+        }
+
+        [HttpPost("authorize")]
+        public async Task<IActionResult> Authorize()
+        {
+            HttpResponseMessage response = await userServiceClient.AuthorizeUserAsync();
+            return new HttpResponseMessageResult(response);
+        }
+
+        [HttpPost("login")]
+        public async Task<IActionResult> Login([FromBody] UserLogin userLogin)
+        {
+            HttpResponseMessage response = await userServiceClient.LoginUserAsync(userLogin);
+            return new HttpResponseMessageResult(response);
+        }
+
+        [HttpPost("logout")]
+        public async Task<IActionResult> Logout()
+        {
+            HttpResponseMessage response = await userServiceClient.LogoutUserAsync();
+            return new HttpResponseMessageResult(response);
+        }
+
+        [HttpGet()]
+        public async Task<IActionResult> GetUsers()
+        {
+            HttpResponseMessage response = await userServiceClient.GetUsersAsync();
+            return new HttpResponseMessageResult(response);
+        }
+
+        [HttpGet("{id}")]
+        public async Task<IActionResult> GetUser(int id)
+        {
+            HttpResponseMessage response = await userServiceClient.GetUserAsync(id);
+            return new HttpResponseMessageResult(response);
+        }
+
+        [HttpPatch("{id}")]
+        public async Task<IActionResult> UpdateUser(int id, [FromBody] UserUpdateInfo updateInfo)
+        {
+            HttpResponseMessage response = await userServiceClient.UpdateUserAsync(id, updateInfo);
+            return new HttpResponseMessageResult(response);
+        }
+    }
+
+}
diff --git a/GatewayAPI/Dockerfile b/GatewayAPI/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..91552e7d806230d9e91a2ac38b4a877899d87b03
--- /dev/null
+++ b/GatewayAPI/Dockerfile
@@ -0,0 +1,25 @@
+#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
+
+FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
+USER app
+WORKDIR /app
+EXPOSE 8080
+EXPOSE 8081
+
+FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
+ARG BUILD_CONFIGURATION=Release
+WORKDIR /src
+COPY ["GatewayAPI.csproj", "."]
+RUN dotnet restore "./GatewayAPI.csproj"
+COPY . .
+WORKDIR "/src/."
+RUN dotnet build "./GatewayAPI.csproj" -c $BUILD_CONFIGURATION -o /app/build
+
+FROM build AS publish
+ARG BUILD_CONFIGURATION=Release
+RUN dotnet publish "./GatewayAPI.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "GatewayAPI.dll"]
\ No newline at end of file
diff --git a/GatewayAPI/GatewayAPI.csproj b/GatewayAPI/GatewayAPI.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..a6c8e7aed19e4a88d321cabd92a6bc86dbc715f6
--- /dev/null
+++ b/GatewayAPI/GatewayAPI.csproj
@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <Nullable>enable</Nullable>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <UserSecretsId>50dbee94-e07d-4906-85d3-8337755e0027</UserSecretsId>
+    <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
+    <DockerfileContext>.</DockerfileContext>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" />
+    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
+  </ItemGroup>
+
+</Project>
diff --git a/GatewayAPI/GatewayAPI.csproj.user b/GatewayAPI/GatewayAPI.csproj.user
new file mode 100644
index 0000000000000000000000000000000000000000..983ecfc07a3622c3f9e0e73b96ae3e61aada8cb9
--- /dev/null
+++ b/GatewayAPI/GatewayAPI.csproj.user
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ActiveDebugProfile>http</ActiveDebugProfile>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/GatewayAPI/GatewayAPI.http b/GatewayAPI/GatewayAPI.http
new file mode 100644
index 0000000000000000000000000000000000000000..a5bc22a7d7b0f11192f97786eee250cd270ef58a
--- /dev/null
+++ b/GatewayAPI/GatewayAPI.http
@@ -0,0 +1,6 @@
+@GatewayAPI_HostAddress = http://localhost:5267
+
+GET {{GatewayAPI_HostAddress}}/weatherforecast/
+Accept: application/json
+
+###
diff --git a/GatewayAPI/GatewayAPI.sln b/GatewayAPI/GatewayAPI.sln
new file mode 100644
index 0000000000000000000000000000000000000000..018f984ffaca373a57f72a68095a682c7e8f0b3e
--- /dev/null
+++ b/GatewayAPI/GatewayAPI.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34622.214
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GatewayAPI", "GatewayAPI.csproj", "{2ABFA760-35A9-4BF8-ADAF-3751CCC8C20A}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{2ABFA760-35A9-4BF8-ADAF-3751CCC8C20A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2ABFA760-35A9-4BF8-ADAF-3751CCC8C20A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2ABFA760-35A9-4BF8-ADAF-3751CCC8C20A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2ABFA760-35A9-4BF8-ADAF-3751CCC8C20A}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {7FFD5B8C-F828-4EBE-B2B7-888D63CDE589}
+	EndGlobalSection
+EndGlobal
diff --git a/GatewayAPI/HttpResponseMessageResult.cs b/GatewayAPI/HttpResponseMessageResult.cs
new file mode 100644
index 0000000000000000000000000000000000000000..3873c553f6453a6f17bf9731c31873f9c5b02417
--- /dev/null
+++ b/GatewayAPI/HttpResponseMessageResult.cs
@@ -0,0 +1,41 @@
+using Microsoft.AspNetCore.Mvc;
+using System.Net.Http;
+using System.Threading.Tasks;
+
+namespace GatewayAPI
+{
+    public class HttpResponseMessageResult : IActionResult
+    {
+        private readonly HttpResponseMessage responseMessage;
+
+        public HttpResponseMessageResult(HttpResponseMessage responseMessage)
+        {
+            this.responseMessage = responseMessage ?? throw new ArgumentNullException(nameof(responseMessage));
+        }
+
+        public async Task ExecuteResultAsync(ActionContext context)
+        {
+            HttpContext httpContext = context.HttpContext;
+            HttpResponse response = httpContext.Response;
+
+            response.ContentType = "application/json; charset=utf-8";
+
+            // Copy the status code
+            response.StatusCode = (int)responseMessage.StatusCode;
+
+            // Copy the cookies
+            if (responseMessage.Headers.TryGetValues("Set-Cookie", out var cookieValues))
+            {
+                foreach (string cookie in cookieValues)
+                    response.Headers.Append("Set-Cookie", cookie);
+            }
+
+            // Copy the response body directly to the response stream
+            using (Stream responseStream = await responseMessage.Content.ReadAsStreamAsync())
+            {
+                await responseStream.CopyToAsync(response.Body);
+                await response.Body.FlushAsync();
+            }
+        }
+    }
+}
diff --git a/GatewayAPI/Models/FlightCreation.cs b/GatewayAPI/Models/FlightCreation.cs
new file mode 100644
index 0000000000000000000000000000000000000000..e3bdfa48d381f6c4c91fee0691b517b1a0ab763d
--- /dev/null
+++ b/GatewayAPI/Models/FlightCreation.cs
@@ -0,0 +1,15 @@
+namespace GatewayAPI.Models
+{
+    public class FlightCreation
+    {
+        public required string Origin { get; set; }
+        public required string Destination { get; set; }
+        public required DateTime DepartureTime { get; set; }
+        public required DateTime ArrivalTime { get; set; }
+        public required int EconomyCapacity { get; set; }
+        public required int BusinessCapacity { get; set; }
+        public required decimal EconomyPrice { get; set; }
+        public required decimal BusinessPrice { get; set; }
+
+    }
+}
diff --git a/GatewayAPI/Models/UserLogin.cs b/GatewayAPI/Models/UserLogin.cs
new file mode 100644
index 0000000000000000000000000000000000000000..47ae2b3b7eea2c4f248314bec714506cc59dcc01
--- /dev/null
+++ b/GatewayAPI/Models/UserLogin.cs
@@ -0,0 +1,9 @@
+namespace GatewayAPI.Models
+{
+    public class UserLogin
+    {
+        public required string Username { get; set; }
+        public required string Password { get; set; }
+
+    }
+}
diff --git a/GatewayAPI/Models/UserRegistration.cs b/GatewayAPI/Models/UserRegistration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..dc94c025e13b9b705c39b251ee69d33e8fbc2d3f
--- /dev/null
+++ b/GatewayAPI/Models/UserRegistration.cs
@@ -0,0 +1,11 @@
+namespace GatewayAPI.Models
+{
+    public class UserRegistration
+    {
+        public required string Username { get; set; }
+        public required string Email { get; set; }
+        public required string Password { get; set; }
+        public required int UserType { get; set; }
+
+    }
+}
diff --git a/GatewayAPI/Models/UserUpdateInfo.cs b/GatewayAPI/Models/UserUpdateInfo.cs
new file mode 100644
index 0000000000000000000000000000000000000000..bf4c9c3b88fce116182686f62ceb7e3051c3fcd5
--- /dev/null
+++ b/GatewayAPI/Models/UserUpdateInfo.cs
@@ -0,0 +1,9 @@
+namespace GatewayAPI.Models
+{
+    public class UserUpdateInfo
+    {
+        public string? Username { get; set; }
+        public string? Email { get; set; }
+        public string? Password { get; set; }
+    }
+}
diff --git a/GatewayAPI/Program.cs b/GatewayAPI/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..8f7722be178b40d5bf7ba13ae48ee1f711801caf
--- /dev/null
+++ b/GatewayAPI/Program.cs
@@ -0,0 +1,27 @@
+using GatewayAPI;
+
+var builder = WebApplication.CreateBuilder(args);
+
+// Add services to the container.
+builder.Services.AddHttpContextAccessor();
+builder.Services.AddTransient<RequestCookieHandler>();
+builder.Services.AddControllers();
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddSwaggerGen();
+
+// Add Http Typed Clients for each Microservice
+builder.Services.AddHttpClients(builder.Configuration);
+
+var app = builder.Build();
+
+// Configure the HTTP request pipeline.
+if (app.Environment.IsDevelopment())
+{
+    app.UseSwagger();
+    app.UseSwaggerUI();
+}
+
+//app.UseHttpsRedirection();
+app.UseAuthorization();
+app.MapControllers();
+app.Run();
diff --git a/GatewayAPI/Properties/launchSettings.json b/GatewayAPI/Properties/launchSettings.json
new file mode 100644
index 0000000000000000000000000000000000000000..bf79d5709995c33286eba3471cf4872823ff1759
--- /dev/null
+++ b/GatewayAPI/Properties/launchSettings.json
@@ -0,0 +1,52 @@
+{
+  "profiles": {
+    "http": {
+      "commandName": "Project",
+      "launchBrowser": true,
+      "launchUrl": "swagger",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      },
+      "dotnetRunMessages": true,
+      "applicationUrl": "http://localhost:5267"
+    },
+    "https": {
+      "commandName": "Project",
+      "launchBrowser": true,
+      "launchUrl": "swagger",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      },
+      "dotnetRunMessages": true,
+      "applicationUrl": "https://localhost:7130;http://localhost:5267"
+    },
+    "IIS Express": {
+      "commandName": "IISExpress",
+      "launchBrowser": true,
+      "launchUrl": "swagger",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    },
+    "Container (Dockerfile)": {
+      "commandName": "Docker",
+      "launchBrowser": true,
+      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
+      "environmentVariables": {
+        "ASPNETCORE_HTTPS_PORTS": "8081",
+        "ASPNETCORE_HTTP_PORTS": "8080"
+      },
+      "publishAllPorts": true,
+      "useSSL": true
+    }
+  },
+  "$schema": "http://json.schemastore.org/launchsettings.json",
+  "iisSettings": {
+    "windowsAuthentication": false,
+    "anonymousAuthentication": true,
+    "iisExpress": {
+      "applicationUrl": "http://localhost:52758",
+      "sslPort": 44344
+    }
+  }
+}
\ No newline at end of file
diff --git a/GatewayAPI/RequestCookieHandler .cs b/GatewayAPI/RequestCookieHandler .cs
new file mode 100644
index 0000000000000000000000000000000000000000..11a59596adc6a9ae9a0a51f2e6904f42f09fe4bc
--- /dev/null
+++ b/GatewayAPI/RequestCookieHandler .cs	
@@ -0,0 +1,36 @@
+using System.Net;
+
+namespace GatewayAPI
+{
+    public class RequestCookieHandler : DelegatingHandler
+    {
+        private readonly IHttpContextAccessor httpContextAccessor;
+
+        public RequestCookieHandler(IHttpContextAccessor httpContextAccessor)
+        {
+            this.httpContextAccessor = httpContextAccessor;
+        }
+
+        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
+        {
+            HttpContext? context = httpContextAccessor.HttpContext;
+
+            if (context?.Request.Cookies != null && request.RequestUri != null)
+            {
+                CookieContainer cookieContainer = new CookieContainer();
+                foreach (KeyValuePair<string, string> cookie in context.Request.Cookies)
+                {
+                    if (!string.IsNullOrEmpty(cookie.Value) && (cookie.Key == "AccessToken" || cookie.Key == "RefreshToken"))
+                        cookieContainer.Add(request.RequestUri, new Cookie(cookie.Key, cookie.Value));
+                }
+
+                var cookieHeader = cookieContainer.GetCookieHeader(request.RequestUri);
+                if (!string.IsNullOrEmpty(cookieHeader))
+                    request.Headers.Add("Cookie", cookieHeader);
+            }
+
+            return await base.SendAsync(request, cancellationToken);
+        }
+
+    }
+}
diff --git a/GatewayAPI/ServiceCollectionExtensions.cs b/GatewayAPI/ServiceCollectionExtensions.cs
new file mode 100644
index 0000000000000000000000000000000000000000..7235c816dcbe5767cfb5c3ef2ccdce5d583e42c4
--- /dev/null
+++ b/GatewayAPI/ServiceCollectionExtensions.cs
@@ -0,0 +1,26 @@
+using GatewayAPI.Clients.FlightService;
+using GatewayAPI.Clients.UserService;
+using System.Runtime.CompilerServices;
+
+namespace GatewayAPI
+{
+    public static class ServiceCollectionExtensions
+    {
+        public static IServiceCollection AddHttpClients(this IServiceCollection services, ConfigurationManager configurationManager)
+        {
+            services.AddHttpClient<IUserServiceClient, UserServiceClient>(client =>
+            {
+                string baseUrl = configurationManager["UserMicroservice:BaseUrl"] ?? throw new InvalidOperationException("UserMicroservice BaseUrl is not configured.");
+                client.BaseAddress = new Uri(baseUrl.EndsWith("/") ? baseUrl : baseUrl + "/");
+            }).AddHttpMessageHandler<RequestCookieHandler>();
+
+            services.AddHttpClient<IFlightServiceClient, FlightServiceClient>(client =>
+            {
+                string baseUrl = configurationManager["FlightMicroservice:BaseUrl"] ?? throw new InvalidOperationException("FlightMicroservice BaseUrl is not configured.");
+                client.BaseAddress = new Uri(baseUrl.EndsWith("/") ? baseUrl : baseUrl + "/");
+            }).AddHttpMessageHandler<RequestCookieHandler>();
+
+            return services;
+        }
+    }
+}
diff --git a/GatewayAPI/appsettings.Development.json b/GatewayAPI/appsettings.Development.json
new file mode 100644
index 0000000000000000000000000000000000000000..0c208ae9181e5e5717e47ec1bd59368aebc6066e
--- /dev/null
+++ b/GatewayAPI/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft.AspNetCore": "Warning"
+    }
+  }
+}
diff --git a/GatewayAPI/appsettings.json b/GatewayAPI/appsettings.json
new file mode 100644
index 0000000000000000000000000000000000000000..f0c8836097302b9aad3a4302088f49f88bc4e46a
--- /dev/null
+++ b/GatewayAPI/appsettings.json
@@ -0,0 +1,15 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft.AspNetCore": "Warning"
+    }
+  },
+  "AllowedHosts": "*",
+  "UserMicroservice": {
+    "BaseUrl": "http://localhost:5089"
+  },
+  "FlightMicroservice": {
+    "BaseUrl": "http://localhost:5175"
+  }
+}
diff --git a/UserMicroservice/Controllers/UserController.cs b/UserMicroservice/Controllers/UserController.cs
index ea86b63444c803bc1bd97876e7df6cc79e646e33..b14e10802f0ae5c083d00f51021e68e12bfc09dd 100644
--- a/UserMicroservice/Controllers/UserController.cs
+++ b/UserMicroservice/Controllers/UserController.cs
@@ -1,5 +1,6 @@
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
 using System.Security.Claims;
 using UserMicroservice.Models;
 using UserMicroservice.Services;
@@ -31,9 +32,10 @@ namespace UserMicroservice.Controllers
                 if (user == null)
                     return BadRequest();
 
-                return authenticateUser(user.Id);
-
-            } catch (InvalidOperationException ex)
+                setAuthCookies(user.Id);
+                return Ok(new { user.Id, user.Username, user.Email, user.Type });
+            }
+            catch (InvalidOperationException ex)
             {
                 return BadRequest(ex.Message);
             }
@@ -57,7 +59,8 @@ namespace UserMicroservice.Controllers
             if (!int.TryParse(userIdString, out int userId))
                 return BadRequest("User ID is invalid.");
 
-            return authenticateUser(userId);
+            setAuthCookies(userId);
+            return Ok();
         }
 
         // POST: api/User/login
@@ -68,14 +71,15 @@ namespace UserMicroservice.Controllers
             if(user == null)
                 return Unauthorized();
 
-            return authenticateUser(user.Id);
+            setAuthCookies(user.Id);
+            return Ok(new { user.Id, user.Username, user.Email, user.Type });
         }
 
-        private IActionResult authenticateUser(int userId)
+        private void setAuthCookies(int userId)
         {
             AuthTokenPair authToken = _authService.AuthenticateUser(userId);
             if (authToken == null)
-                return BadRequest();
+                throw new ArgumentNullException(nameof(authToken));
 
             // Set the access token as an HttpOnly cookie
             Response.Cookies.Append("AccessToken", authToken.AccessToken, new CookieOptions
@@ -94,8 +98,6 @@ namespace UserMicroservice.Controllers
                 SameSite = SameSiteMode.Strict,
                 Expires = DateTimeOffset.UtcNow.AddDays(2)
             });
-
-            return Ok();
         }
 
         // POST: api/User/logout
@@ -153,8 +155,28 @@ namespace UserMicroservice.Controllers
             User? user = _userService.GetUser(id);
             if(user == null)
                 return NotFound($"User with {id} doesnt exist");
-            
-            return Ok(user);
+
+            return Ok(new{ user.Id, user.Username, user.Email, user.Type });
+        }
+
+        // PUT: api/User/{id}
+        [Authorize]
+        [HttpPatch("{id}")]
+        public IActionResult UpdateUser(int id, [FromBody] UpdateUserModel model)
+        {
+            try
+            {
+                _userService.UpdateUser(id, model.Username, model.Email, model.Password);
+                return Ok();
+            } 
+            catch (KeyNotFoundException exception)
+            {
+                return NotFound(exception.Message);
+            }
+            catch (DbUpdateException exception) 
+            {
+                return BadRequest(exception.Message);            
+            }
         }
 
     }
diff --git a/UserMicroservice/Models/UpdateUserModel.cs b/UserMicroservice/Models/UpdateUserModel.cs
new file mode 100644
index 0000000000000000000000000000000000000000..bda556ab8afd0285533f5a565d9ff8caf646e635
--- /dev/null
+++ b/UserMicroservice/Models/UpdateUserModel.cs
@@ -0,0 +1,9 @@
+namespace UserMicroservice.Models
+{
+    public class UpdateUserModel
+    {
+        public string? Username { get; set; }
+        public string? Email { get; set; }
+        public string? Password { get; set; }
+    }
+}
diff --git a/UserMicroservice/Services/IUserService.cs b/UserMicroservice/Services/IUserService.cs
index 2a4e75bc8dffa98a58c9d1f1925491aebecd1730..0e6deffc39d5b7b37e3778f0c96882df235b1878 100644
--- a/UserMicroservice/Services/IUserService.cs
+++ b/UserMicroservice/Services/IUserService.cs
@@ -10,7 +10,7 @@ namespace UserMicroservice.Services
         User? GetUser(string username, string password);
         List<User> GetUsers();
         User CreateUser(string email, string userName, string password, UserType UserType);
-        User UpdateUser(User updatedUser);
+        void UpdateUser(int id, string? username, string? email, string? password);
         bool DeleteUser(string username);
         User? GetUserByEmail(string email);
     }
diff --git a/UserMicroservice/Services/UserService.cs b/UserMicroservice/Services/UserService.cs
index 9288ae8b3754d62c7759fe1e02eff482e8574b11..59c0f37697e912984c773e7ea882771b3a4e1030 100644
--- a/UserMicroservice/Services/UserService.cs
+++ b/UserMicroservice/Services/UserService.cs
@@ -80,17 +80,32 @@ namespace UserMicroservice.Services
             return user;            
         }
 
-        public User UpdateUser(User updatedUser)
+        public void UpdateUser(int id, string? username, string? email, string? password)
         {
-            _context.Users
-                        .Where(user => user.Id == updatedUser.Id)
+            User? user = GetUser(id);
+            if(user == null)
+                throw new KeyNotFoundException($"A User with the provided Id {id} doesnt exist");
+            
+            string updatedEmail = string.IsNullOrEmpty(email) ? user.Email : email;
+            string updatedUserName = string.IsNullOrEmpty(username) ? user.Username : username;
+            string updatedPassword = user.PasswordHash;
+
+            if (!string.IsNullOrEmpty(password)) {
+                user.SetPasswordHash(_passwordHasher, password);
+                updatedPassword = user.PasswordHash;
+            }
+
+            int affectedRows = _context.Users
+                        .Where(user => user.Id == id)
                         .ExecuteUpdate(setters => setters
-                            .SetProperty(user => user.Username, updatedUser.Username)
-                            .SetProperty(user => user.PasswordHash, updatedUser.PasswordHash));
+                            .SetProperty(user => user.Username, updatedUserName)
+                            .SetProperty(user => user.Email, updatedEmail)
+                            .SetProperty(user => user.PasswordHash, updatedPassword));
 
             _context.SaveChanges();
 
-            return updatedUser;
+            if (affectedRows == 0)
+                throw new DbUpdateException("Operation was not able to update the Database");
         }
     }
 }
diff --git a/docker-compose.yml b/docker-compose.yml
index 83dca104e1be91f60ddf7a9f28865f2269c9ab72..109ae714e84c633d4d1f750a619d017a61d67d84 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,5 +1,4 @@
 version: '3.8'
-
 services:
   usermicroservice:
     build:
@@ -12,30 +11,52 @@ services:
       - DOTNET_RUNNING_IN_CONTAINER=true
       - ConnectionStrings__DefaultConnection=Server=host.docker.internal;Port=${DB_PORT};Database=${DB_NAME};User=${DB_USER};Password=${DB_PASSWORD};CharSet=${DB_CHARSET}
       - Jwt__Key=0QTrd3jToEYj205k01A2R87Hc5YpqDNeywg7JzQpczs=
-      - Jwt__Issuer=http://localhost:${USER_MICROSERVICE_PORT}
-      - Jwt__Audience=http://localhost:${USER_MICROSERVICE_PORT}
+      - Jwt__Issuer=http://usermicroservice:8080
+      - Jwt__Audience=http://usermicroservice:8080
 
   flightmicroservice:
     build:
       context: ./FlightMicroservice
     image: flightmicroservice:${IMAGE_TAG}
     ports:
-      - "5175:8080"
+      - "${FLIGHT_MICROSERVICE_PORT}:8080"
     environment:
       - ASPNETCORE_ENVIRONMENT=Production
       - DOTNET_RUNNING_IN_CONTAINER=true
       - ConnectionStrings__DefaultConnection=Server=host.docker.internal;Port=${DB_PORT};Database=${DB_NAME};User=${DB_USER};Password=${DB_PASSWORD};CharSet=${DB_CHARSET}
       - Jwt__Key=0QTrd3jToEYj205k01A2R87Hc5YpqDNeywg7JzQpczs=
-      - Jwt__Issuer=http://localhost:${USER_MICROSERVICE_PORT}
-      - Jwt__Audience=http://localhost:${USER_MICROSERVICE_PORT}
+      - Jwt__Issuer=http://usermicroservice:8080
+      - Jwt__Audience=http://usermicroservice:8080
+
+  gatewayapi:
+    build:
+      context: ./GatewayAPI
+    image: gatewayapi:${IMAGE_TAG}
+    ports:
+      - "${GATEWAY_API_PORT}:8080"
+    environment:
+      - ASPNETCORE_ENVIRONMENT=Production
+      - DOTNET_RUNNING_IN_CONTAINER=true
+      - UserMicroservice__BaseUrl=http://usermicroservice:8080
+      - FlightMicroservice__BaseUrl=http://flightmicroservice:8080
 
   client:
     build:
       context: ./client
     image: client:${IMAGE_TAG}
     ports:
-      - "4200:4200"
-
-
+      - "${CLIENT_PORT}:4200"
 
-# ... other services
+  db:
+    image: mysql:${MYSQL_IMAGE_TAG}
+    command: --default-authentication-plugin=mysql_native_password
+    restart: always
+    environment:
+      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
+      MYSQL_DATABASE: ${DB_NAME}
+      MYSQL_USER: ${DB_USER}
+      MYSQL_PASSWORD: ${DB_PASSWORD}
+    volumes:
+      - ./Database:/docker-entrypoint-initdb.d
+    ports:
+      - "${DB_PORT}:3306"