diff --git a/src/backend/.config/dotnet-tools.json b/src/backend/.config/dotnet-tools.json index e7d553a..fb1dd62 100644 --- a/src/backend/.config/dotnet-tools.json +++ b/src/backend/.config/dotnet-tools.json @@ -36,6 +36,13 @@ "dotnet-outdated" ], "rollForward": false + }, + "refitter": { + "version": "1.4.0", + "commands": [ + "refitter" + ], + "rollForward": false } } } \ No newline at end of file diff --git a/src/backend/ApiClient/ApiClient.csproj b/src/backend/ApiClient/ApiClient.csproj new file mode 100644 index 0000000..7be0d5f --- /dev/null +++ b/src/backend/ApiClient/ApiClient.csproj @@ -0,0 +1,19 @@ + + + + Exe + net9.0 + enable + enable + + + + + + + + + + + + diff --git a/src/backend/ApiClient/Program.cs b/src/backend/ApiClient/Program.cs new file mode 100644 index 0000000..501d770 --- /dev/null +++ b/src/backend/ApiClient/Program.cs @@ -0,0 +1,5 @@ +using Refit; +using WebApi.Client; + +var testApiClient = RestService.For("https://localhost:44380"); +await testApiClient.Ping(); \ No newline at end of file diff --git a/src/backend/ApiClient/WebApiClient.cs b/src/backend/ApiClient/WebApiClient.cs new file mode 100644 index 0000000..5efb3c5 --- /dev/null +++ b/src/backend/ApiClient/WebApiClient.cs @@ -0,0 +1,424 @@ +// +// This code was generated by Refitter. +// + + +using Refit; +using System.Collections.Generic; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +#nullable enable annotations + +namespace WebApi.Client +{ + [System.CodeDom.Compiler.GeneratedCode("Refitter", "1.4.0.0")] + public partial interface IExampleAPI + { + /// Gets a list of all blogs. + /// OK + /// + /// Thrown when the request returns a non-success status code: + /// + /// + /// Status + /// Description + /// + /// + /// 500 + /// Internal Server Error + /// + /// + /// + [Headers("Accept: application/json")] + [Get("/Blogging/blog")] + Task> GetBlogs(); + + /// Creates a new blog or updates an existing one. + /// The blog data transfer object + /// OK + /// + /// Thrown when the request returns a non-success status code: + /// + /// + /// Status + /// Description + /// + /// + /// 500 + /// Internal Server Error + /// + /// + /// + [Headers("Accept: application/json")] + [Post("/Blogging/blog")] + Task PostBlog([Body] BlogDto body); + + /// Gets a specific blog by ID. + /// The ID of the blog. + /// OK + /// + /// Thrown when the request returns a non-success status code: + /// + /// + /// Status + /// Description + /// + /// + /// 500 + /// Internal Server Error + /// + /// + /// + [Headers("Accept: application/json")] + [Get("/Blogging/blog/{id}")] + Task GetBlog(int id); + + /// Gets a list of posts related to a specific blog. + /// The ID of the blog + /// OK + /// + /// Thrown when the request returns a non-success status code: + /// + /// + /// Status + /// Description + /// + /// + /// 500 + /// Internal Server Error + /// + /// + /// + [Headers("Accept: application/json")] + [Get("/Blogging/blog/{blogId}/posts")] + Task> GetPosts(int blogId); + + /// Gets a specific post by ID. + /// The ID of the post + /// OK + /// + /// Thrown when the request returns a non-success status code: + /// + /// + /// Status + /// Description + /// + /// + /// 500 + /// Internal Server Error + /// + /// + /// + [Headers("Accept: application/json")] + [Get("/Blogging/post/{id}")] + Task GetPost(int id); + + /// Creates a new post. + /// The post data transfer object + /// OK + /// + /// Thrown when the request returns a non-success status code: + /// + /// + /// Status + /// Description + /// + /// + /// 500 + /// Internal Server Error + /// + /// + /// + [Headers("Accept: application/json")] + [Post("/Blogging/post")] + Task PostPost([Body] PostDto body); + + /// Sends a message using the MessageSender service. + /// OK + /// + /// Thrown when the request returns a non-success status code: + /// + /// + /// Status + /// Description + /// + /// + /// 500 + /// Internal Server Error + /// + /// + /// + [Headers("Accept: application/json")] + [Get("/SendMessage")] + Task SendMessage(); + + /// Returns ok + /// OK + /// + /// Thrown when the request returns a non-success status code: + /// + /// + /// Status + /// Description + /// + /// + /// 500 + /// Internal Server Error + /// + /// + /// + [Headers("Accept: application/json")] + [Get("/Service/ping")] + Task Ping(); + + /// Returns version + /// OK + /// + /// Thrown when the request returns a non-success status code: + /// + /// + /// Status + /// Description + /// + /// + /// 500 + /// Internal Server Error + /// + /// + /// + [Headers("Accept: application/json")] + [Get("/Service/version")] + Task Version(); + + /// Returns weather forecast + /// OK + /// + /// Thrown when the request returns a non-success status code: + /// + /// + /// Status + /// Description + /// + /// + /// 500 + /// Internal Server Error + /// + /// + /// + [Headers("Accept: application/json")] + [Get("/WeatherForecast")] + Task> GetWeatherForecast(); + + + } + +} + +//---------------------- +// +// Generated using the NSwag toolchain v14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0)) (http://NSwag.org) +// +//---------------------- + +#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended." +#pragma warning disable 114 // Disable "CS0114 '{derivedDto}.RaisePropertyChanged(String)' hides inherited member 'dtoBase.RaisePropertyChanged(String)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword." +#pragma warning disable 472 // Disable "CS0472 The result of the expression is always 'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?' +#pragma warning disable 612 // Disable "CS0612 '...' is obsolete" +#pragma warning disable 649 // Disable "CS0649 Field is never assigned to, and will always have its default value null" +#pragma warning disable 1573 // Disable "CS1573 Parameter '...' has no matching param tag in the XML comment for ... +#pragma warning disable 1591 // Disable "CS1591 Missing XML comment for publicly visible type or member ..." +#pragma warning disable 8073 // Disable "CS8073 The result of the expression is always 'false' since a value of type 'T' is never equal to 'null' of type 'T?'" +#pragma warning disable 3016 // Disable "CS3016 Arrays as attribute arguments is not CLS-compliant" +#pragma warning disable 8603 // Disable "CS8603 Possible null reference return" +#pragma warning disable 8604 // Disable "CS8604 Possible null reference argument for parameter" +#pragma warning disable 8625 // Disable "CS8625 Cannot convert null literal to non-nullable reference type" +#pragma warning disable 8765 // Disable "CS8765 Nullability of type of parameter doesn't match overridden member (possibly because of nullability attributes)." + +namespace WebApi.Client +{ + using System = global::System; + + + + /// + /// Blog DTO + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class BlogDto + { + /// + /// Gets or sets the unique identifier for the blog. + /// + + [JsonPropertyName("blogId")] + public int BlogId { get; set; } + + /// + /// Gets or sets the title of the blog. + /// + + [JsonPropertyName("title")] + public string Title { get; set; } + + /// + /// Gets or sets the URL of the blog. + /// + + [JsonPropertyName("url")] + public string Url { get; set; } + + } + + /// + /// Post DTO + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class PostDto + { + /// + /// Gets or sets the unique identifier for the post. + /// + + [JsonPropertyName("postId")] + public int PostId { get; set; } + + /// + /// Gets or sets the title of the post. + /// + + [JsonPropertyName("title")] + public string Title { get; set; } + + /// + /// Gets or sets the content of the post. + /// + + [JsonPropertyName("content")] + public string Content { get; set; } + + /// + /// Gets or sets the unique identifier of the blog to which the post belongs. + /// + + [JsonPropertyName("blogId")] + public int BlogId { get; set; } + + } + + /// + /// Represents a generic value container for value types. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class StringGenericValue + { + /// + /// Gets or sets the value stored in the container. + /// + + [JsonPropertyName("value")] + public string Value { get; set; } + + } + + /// + /// Represents version information for an assembly, including constants, environment name, version, and informational + ///
version. + ///
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class VersionInformation + { + /// + /// Constants defined in the assembly, if any. + /// + + [JsonPropertyName("constants")] + public ICollection Constants { get; set; } + + /// + /// The version of the assembly. + /// + + [JsonPropertyName("version")] + public string Version { get; set; } + + /// + /// The informational version of the assembly, which may include additional details. + /// + + [JsonPropertyName("informationalVersion")] + public string InformationalVersion { get; set; } + + /// + /// The name of the environment where the application is running. + /// + + [JsonPropertyName("environmentName")] + public string EnvironmentName { get; set; } + + } + + /// + /// Weather forecast model + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class WeatherForecast + { + /// + /// Date of forecast + /// + + [JsonPropertyName("date")] + [JsonConverter(typeof(DateFormatConverter))] + public System.DateTimeOffset Date { get; set; } + + /// + /// Temperature in celsius + /// + + [JsonPropertyName("temperatureC")] + public int TemperatureC { get; set; } + + /// + /// Summary text + /// + + [JsonPropertyName("summary")] + public string Summary { get; set; } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] + internal class DateFormatConverter : JsonConverter + { + public override System.DateTimeOffset Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) + { + var dateTime = reader.GetString(); + if (dateTime == null) + { + throw new System.Text.Json.JsonException("Unexpected JsonTokenType.Null"); + } + + return System.DateTimeOffset.Parse(dateTime); + } + + public override void Write(System.Text.Json.Utf8JsonWriter writer, System.DateTimeOffset value, System.Text.Json.JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString("yyyy-MM-dd")); + } + } + + +} + +#pragma warning restore 108 +#pragma warning restore 114 +#pragma warning restore 472 +#pragma warning restore 612 +#pragma warning restore 1573 +#pragma warning restore 1591 +#pragma warning restore 8073 +#pragma warning restore 3016 +#pragma warning restore 8603 +#pragma warning restore 8604 +#pragma warning restore 8625 \ No newline at end of file diff --git a/src/backend/ApiClient/packages.lock.json b/src/backend/ApiClient/packages.lock.json new file mode 100644 index 0000000..c540b6f --- /dev/null +++ b/src/backend/ApiClient/packages.lock.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "dependencies": { + "net9.0": { + "Refit": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "gXRmIy3Va0mwwr8usnqVRQFoFIJaJGlWTTXBlwxIkHB/xwXnq1Ybs1YNA2BM1O4G46JLLlGjg6YOwrTZusuY3Q==" + } + }, + "net9.0/linux-musl-x64": {}, + "net9.0/win-x64": {} + } +} \ No newline at end of file diff --git a/src/backend/Backend.sln b/src/backend/Backend.sln index cd8ae57..67fc9fa 100644 --- a/src/backend/Backend.sln +++ b/src/backend/Backend.sln @@ -36,6 +36,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "log", "log", "{0BD80B55-00B EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NugetDistSample", "..\..\shared\NugetDistSample\NugetDistSample.csproj", "{FC33B9B5-7F55-4C06-A9CE-811FE31DDE2D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiClient", "ApiClient\ApiClient.csproj", "{2EAC07D7-36C3-48E3-9C4D-98CEB9AE8CA4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -58,6 +60,10 @@ Global {FC33B9B5-7F55-4C06-A9CE-811FE31DDE2D}.Debug|Any CPU.Build.0 = Debug|Any CPU {FC33B9B5-7F55-4C06-A9CE-811FE31DDE2D}.Release|Any CPU.ActiveCfg = Release|Any CPU {FC33B9B5-7F55-4C06-A9CE-811FE31DDE2D}.Release|Any CPU.Build.0 = Release|Any CPU + {2EAC07D7-36C3-48E3-9C4D-98CEB9AE8CA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2EAC07D7-36C3-48E3-9C4D-98CEB9AE8CA4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2EAC07D7-36C3-48E3-9C4D-98CEB9AE8CA4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2EAC07D7-36C3-48E3-9C4D-98CEB9AE8CA4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/backend/Directory.Build.props b/src/backend/Directory.Build.props index 7d1c2a0..1f3bbb4 100644 --- a/src/backend/Directory.Build.props +++ b/src/backend/Directory.Build.props @@ -17,10 +17,6 @@ - - <_Parameter1>"$(DefineConstants)" - - diff --git a/src/backend/WebApi/WebApi.csproj b/src/backend/WebApi/WebApi.csproj index 1ffba7f..488cc78 100644 --- a/src/backend/WebApi/WebApi.csproj +++ b/src/backend/WebApi/WebApi.csproj @@ -35,6 +35,9 @@ + + <_Parameter1>"$(DefineConstants)" +