{"id":1980,"date":"2024-10-31T18:36:19","date_gmt":"2024-10-31T16:36:19","guid":{"rendered":"https:\/\/epicmarketing.co.il\/notebook\/?p=1980"},"modified":"2024-11-01T08:47:02","modified_gmt":"2024-11-01T06:47:02","slug":"building-restful-apis","status":"publish","type":"post","link":"https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/","title":{"rendered":"Building RESTful APIs"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">Learning Objectives:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Understand <strong>best practices<\/strong> for designing RESTful APIs, including resource modeling and endpoint conventions.<\/li>\n\n\n\n<li>Learn how to use <strong>JSON serialization<\/strong> with <code>System.Text.Json<\/code> for data conversion.<\/li>\n\n\n\n<li>Understand how to <strong>validate requests<\/strong> using data annotations and fluent validation in ASP.NET Core.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">RESTful Design<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What is REST?<\/strong> <strong>REST (Representational State Transfer)<\/strong> is an architectural style for designing networked applications. RESTful APIs use HTTP methods (GET, POST, PUT, DELETE) to manage resources and are easy to use, scalable, and widely adopted for web services.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Key RESTful Concepts<\/strong>:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Resource Modeling<\/strong>: Resources are the entities represented in the API, such as products, users, or orders. Resources are typically exposed via <strong>URLs<\/strong>.<\/li>\n\n\n\n<li><strong>HTTP Methods<\/strong>:\n<ul class=\"wp-block-list\">\n<li><strong>GET<\/strong>: Retrieve data.<\/li>\n\n\n\n<li><strong>POST<\/strong>: Create a new resource.<\/li>\n\n\n\n<li><strong>PUT<\/strong>: Update an existing resource.<\/li>\n\n\n\n<li><strong>DELETE<\/strong>: Remove a resource.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Example of Resource URL<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>\/api\/products<\/code>: Represents a collection of products.<\/li>\n\n\n\n<li><code>\/api\/products\/{id}<\/code>: Represents a single product identified by <code>{id}<\/code>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Example: Creating RESTful Endpoints<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n&#x5B;ApiController]\n&#x5B;Route(&quot;api\/products&quot;)]\npublic class ProductController : ControllerBase\n{\n    &#x5B;HttpGet]\n    public IActionResult GetProducts()\n    {\n        return Ok(new List&lt;string&gt; { &quot;Product1&quot;, &quot;Product2&quot;, &quot;Product3&quot; });\n    }\n\n    &#x5B;HttpGet(&quot;{id}&quot;)]\n    public IActionResult GetProductById(int id)\n    {\n        if (id &lt;= 0)\n        {\n            return BadRequest(&quot;Invalid product ID.&quot;);\n        }\n        return Ok($&quot;Product with ID: {id}&quot;);\n    }\n\n    &#x5B;HttpPost]\n    public IActionResult CreateProduct(&#x5B;FromBody] string product)\n    {\n        return CreatedAtAction(nameof(GetProductById), new { id = 4 }, product);\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Real-Life Example<\/strong>: In an e-commerce system, this API could be used to list products, get product details by ID, or add a new product.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Data Serialization<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What is Data Serialization?<\/strong> <strong>Serialization<\/strong> is the process of converting an object into a format that can be easily transmitted or stored, such as <strong>JSON<\/strong>. <strong>Deserialization<\/strong> is the reverse\u2014converting JSON back into an object.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In ASP.NET Core, <code>System.Text.Json<\/code> is used for JSON serialization, which is lightweight and high-performance compared to alternatives.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Serializing an Object to JSON<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nusing System.Text.Json;\n\nvar product = new { Id = 1, Name = &quot;Laptop&quot;, Price = 999.99 };\nstring json = JsonSerializer.Serialize(product);\nConsole.WriteLine(json);\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Output<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n{&quot;Id&quot;:1,&quot;Name&quot;:&quot;Laptop&quot;,&quot;Price&quot;:999.99}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Deserializing JSON to an Object<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nvar jsonString = &quot;{\\&quot;Id\\&quot;:1,\\&quot;Name\\&quot;:\\&quot;Laptop\\&quot;,\\&quot;Price\\&quot;:999.99}&quot;;\nvar productObj = JsonSerializer.Deserialize&lt;Product&gt;(jsonString);\nConsole.WriteLine(productObj.Name); \/\/ Output: Laptop\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Real-Life Example<\/strong>: In a <strong>user management<\/strong> system, JSON serialization is used to convert user objects to JSON format for sending as responses to clients.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Request Validation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Why Validate Requests?<\/strong> Validating incoming requests ensures that the data sent to the server is correct and meets certain criteria. This helps in preventing bad data from entering the system, thereby reducing runtime errors.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>1. Data Annotations<\/strong>:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Data Annotations<\/strong> are attributes used on model properties to specify validation rules.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class Product\n{\n    public int Id { get; set; }\n\n    &#x5B;Required(ErrorMessage = &quot;Name is required&quot;)]\n    &#x5B;StringLength(50, ErrorMessage = &quot;Name length can&#039;t be more than 50.&quot;)]\n    public string Name { get; set; }\n\n    &#x5B;Range(0.01, 10000, ErrorMessage = &quot;Price must be between 0.01 and 10000.&quot;)]\n    public decimal Price { get; set; }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This ensures that a product has a <strong>Name<\/strong> and <strong>Price<\/strong> that meets certain conditions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Data annotations are <strong>attributes<\/strong> applied directly to the properties of a model. They provide <strong>basic validation rules<\/strong> directly in the model class.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Advantages<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Simplicity<\/strong>: Data annotations are simple and easy to use.<\/li>\n\n\n\n<li><strong>Consistency<\/strong>: The validation rules are applied consistently across all consumers of the model, such as in controllers that use model binding.<\/li>\n\n\n\n<li><strong>Built-in Support<\/strong>: ASP.NET Core's model binding process automatically checks data annotations, which means you don\u2019t need additional code to validate incoming data.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>When to Use Data Annotations<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>When you need <strong>basic, reusable validation<\/strong> directly tied to the model.<\/li>\n\n\n\n<li>When you want the validation logic to be <strong>tightly coupled<\/strong> with the model definition itself.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">2. <strong>Fluent Validation<\/strong>:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>FluentValidation<\/strong> is an external library used for building validation rules fluently.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nusing FluentValidation;\n\npublic class ProductValidator : AbstractValidator&lt;Product&gt;\n{\n    public ProductValidator()\n    {\n        RuleFor(product =&gt; product.Name).NotEmpty().WithMessage(&quot;Name is required&quot;);\n        RuleFor(product =&gt; product.Price).GreaterThan(0).WithMessage(&quot;Price must be greater than 0&quot;);\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>FluentValidation<\/strong> is an <strong>external library<\/strong> that provides a more <strong>fluent, expressive, and flexible<\/strong> way to define validation logic.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Advantages<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Flexible and Powerful<\/strong>: FluentValidation allows for more complex and conditional rules compared to data annotations.<\/li>\n\n\n\n<li><strong>Separation of Concerns<\/strong>: By moving validation to a separate class, you keep the <strong>model<\/strong> clean and <strong>business logic<\/strong> centralized. This aligns with the <strong>single responsibility principle<\/strong>.<\/li>\n\n\n\n<li><strong>Custom Rules<\/strong>: FluentValidation allows defining complex rules that depend on multiple properties or custom logic, which cannot be easily expressed with data annotations.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>When to Use FluentValidation<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>When you need more <strong>advanced and complex validation rules<\/strong>.<\/li>\n\n\n\n<li>When you want to keep validation logic <strong>separate<\/strong> from the model definition.<\/li>\n\n\n\n<li>When you need to <strong>centralize business rules<\/strong> and apply different validation rules under different scenarios (e.g., when creating vs. updating).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Using Validation in Controllers<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n&#x5B;HttpPost]\npublic IActionResult CreateProduct(&#x5B;FromBody] Product product)\n{\n    if (!ModelState.IsValid)\n    {\n        return BadRequest(ModelState);\n    }\n    return CreatedAtAction(nameof(GetProductById), new { id = product.Id }, product);\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Real-Life Example<\/strong>: In a <strong>financial application<\/strong>, validation ensures that transaction amounts are positive and required fields are present, preventing invalid transactions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Examples<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Simple Example: GET Request<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Endpoint to get a list of products.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Code Snippet<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n&#x5B;HttpGet]\npublic IActionResult GetProducts()\n{\n    return Ok(new List&lt;string&gt; { &quot;Product1&quot;, &quot;Product2&quot; });\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Real-Life Example<\/strong>: Used in an e-commerce API to list all available products.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Simple Example: POST Request with Data Annotations<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use data annotations to validate a product model.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Code Snippet<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n&#x5B;HttpPost]\npublic IActionResult CreateProduct(&#x5B;FromBody] Product product)\n{\n    if (!ModelState.IsValid)\n    {\n        return BadRequest(ModelState);\n    }\n    return CreatedAtAction(nameof(GetProductById), new { id = product.Id }, product);\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Real-Life Example<\/strong>: In a user management system, validate user details before saving to the database.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Simple Example: Serialization and Deserialization<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Serialize a product object to JSON.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Code Snippet<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nvar product = new Product { Id = 1, Name = &quot;Laptop&quot;, Price = 1000.0m };\nstring jsonString = JsonSerializer.Serialize(product);\nConsole.WriteLine(jsonString);\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Real-Life Example<\/strong>: Convert a financial transaction object to JSON before sending it to a third-party payment gateway.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Key Takeaways<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>RESTful APIs<\/strong> are designed around resources, and each resource has well-defined endpoints.<\/li>\n\n\n\n<li><strong>Data serialization<\/strong> using <code>System.Text.Json<\/code> is essential for sending data over the network.<\/li>\n\n\n\n<li><strong>Request validation<\/strong> helps ensure data integrity, using either data annotations or fluent validation for more flexibility.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Practical Questions<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>What are the main principles of RESTful API design, and why are they important?<\/li>\n\n\n\n<li>How would you use <code>System.Text.Json<\/code> to serialize and deserialize objects in ASP.NET Core?<\/li>\n\n\n\n<li>How can you validate user input before saving it to the database in an ASP.NET Core API?<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">New Concepts in .NET 8<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>New in .NET 8<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Native AOT Compilation<\/strong>: This feature allows for <strong>ahead-of-time (AOT)<\/strong> compilation, which helps improve performance by generating self-contained executables. For building APIs, this can mean <strong>faster startup times<\/strong>, which is beneficial for scaling in cloud environments.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Add a product to a database example<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This example involves:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Controller<\/strong>: Manages HTTP requests and returns appropriate responses.<\/li>\n\n\n\n<li><strong>Service<\/strong>: Implements business logic, including validation.<\/li>\n\n\n\n<li><strong>Repository<\/strong>: Handles direct interaction with the database.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step-by-Step Full Example<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 1: Create the Product Model<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Define a <code>Product<\/code> model that represents the data structure.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class Product\n{\n    public int Id { get; set; }\n\n    &#x5B;Required(ErrorMessage = &quot;Name is required&quot;)]\n    &#x5B;StringLength(50, ErrorMessage = &quot;Name length can&#039;t be more than 50.&quot;)]\n    public string Name { get; set; }\n\n    &#x5B;Range(0.01, 10000, ErrorMessage = &quot;Price must be between 0.01 and 10000.&quot;)]\n    public decimal Price { get; set; }\n}\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 2: Create the Repository Layer for Database Interaction<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>repository<\/strong> will handle the direct interaction with the database using ADO.NET.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nusing System.Data.SqlClient;\n\npublic interface IProductRepository\n{\n    void AddProduct(Product product);\n}\n\npublic class ProductRepository : IProductRepository\n{\n    private readonly string _connectionString;\n\n    public ProductRepository(string connectionString)\n    {\n        _connectionString = connectionString;\n    }\n\n    public void AddProduct(Product product)\n    {\n        using (SqlConnection connection = new SqlConnection(_connectionString))\n        {\n            try\n            {\n                connection.Open();\n                using (SqlCommand command = new SqlCommand(&quot;AddNewProduct&quot;, connection))\n                {\n                    command.CommandType = System.Data.CommandType.StoredProcedure;\n                    command.Parameters.AddWithValue(&quot;@Name&quot;, product.Name);\n                    command.Parameters.AddWithValue(&quot;@Price&quot;, product.Price);\n                    command.ExecuteNonQuery();\n                }\n            }\n            catch (SqlException ex)\n            {\n                throw new Exception($&quot;Database connection error: {ex.Message}&quot;);\n            }\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Stored Procedure<\/strong>: The <code>AddNewProduct<\/code> stored procedure should be defined in the SQL Server database.<strong>Error Handling<\/strong>: If there's an issue with the connection, an exception is thrown with an error message.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 3: Create the Service Layer for Business Logic<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>service layer<\/strong> implements validation and manages the call to the repository.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nusing FluentValidation;\n\npublic interface IProductService\n{\n    void AddProduct(Product product);\n}\n\npublic class ProductService : IProductService\n{\n    private readonly IProductRepository _productRepository;\n\n    public ProductService(IProductRepository productRepository)\n    {\n        _productRepository = productRepository;\n    }\n\n    public void AddProduct(Product product)\n    {\n        \/\/ Validate the product\n        var validator = new ProductValidator();\n        var validationResult = validator.Validate(product);\n        \n        if (!validationResult.IsValid)\n        {\n            throw new ValidationException(validationResult.Errors);\n        }\n\n        \/\/ If valid, add the product\n        _productRepository.AddProduct(product);\n    }\n}\n\n\/\/ FluentValidation for Product\npublic class ProductValidator : AbstractValidator&lt;Product&gt;\n{\n    public ProductValidator()\n    {\n        RuleFor(product =&gt; product.Name).NotEmpty().WithMessage(&quot;Name is required&quot;);\n        RuleFor(product =&gt; product.Price).GreaterThan(0).WithMessage(&quot;Price must be greater than 0&quot;);\n    }\n}\n<\/pre><\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>The service validates the product using <strong>FluentValidation<\/strong>.<\/li>\n\n\n\n<li>If the product is valid, it calls the repository to add the product.<\/li>\n\n\n\n<li>If validation fails, an exception is thrown with the list of errors.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 4: Create the Product Controller<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>controller<\/strong> receives the HTTP request, manages input, and uses the service to add the product.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nusing Microsoft.AspNetCore.Mvc;\nusing FluentValidation;\n\n&#x5B;ApiController]\n&#x5B;Route(&quot;api\/products&quot;)]\npublic class ProductController : ControllerBase\n{\n    private readonly IProductService _productService;\n\n    public ProductController(IProductService productService)\n    {\n        _productService = productService;\n    }\n\n    &#x5B;HttpPost]\n    public IActionResult AddProduct(&#x5B;FromBody] Product product)\n    {\n        try\n        {\n            _productService.AddProduct(product);\n            return CreatedAtAction(nameof(AddProduct), new { id = product.Id }, product);\n        }\n        catch (ValidationException ex)\n        {\n            return BadRequest(new { Errors = ex.Errors.Select(e =&gt; e.ErrorMessage) });\n        }\n        catch (Exception ex)\n        {\n            return StatusCode(500, new { Error = ex.Message });\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>The <strong>controller<\/strong> handles incoming requests and calls the service.<\/li>\n\n\n\n<li>If there are <strong>validation errors<\/strong>, they are returned with a <code>400 Bad Request<\/code>.<\/li>\n\n\n\n<li>If there is a <strong>database error<\/strong> (or any other issue), a <code>500 Internal Server Error<\/code> is returned with the relevant message.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 5: Configure Dependency Injection in <code>Program.cs<\/code><\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Register the services and repository in the DI container.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nvar builder = WebApplication.CreateBuilder(args);\n\n\/\/ Add services to the container.\nbuilder.Services.AddControllers();\n\n\/\/ Add connection string from appsettings.json or environment variable\nstring connectionString = builder.Configuration.GetConnectionString(&quot;DefaultConnection&quot;);\n\n\/\/ Register repository and service for dependency injection\nbuilder.Services.AddScoped&lt;IProductRepository&gt;(provider =&gt; new ProductRepository(connectionString));\nbuilder.Services.AddScoped&lt;IProductService, ProductService&gt;();\n\nvar app = builder.Build();\n\n\/\/ Configure the HTTP request pipeline.\napp.UseRouting();\napp.UseAuthorization();\n\napp.UseEndpoints(endpoints =&gt;\n{\n    endpoints.MapControllers();\n});\n\napp.Run();\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 6: SQL Stored Procedure Example<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Create a <strong>stored procedure<\/strong> in the SQL Server database to add a new product.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nCREATE PROCEDURE AddNewProduct\n    @Name NVARCHAR(50),\n    @Price DECIMAL(18, 2)\nAS\nBEGIN\n    INSERT INTO Products (Name, Price) VALUES (@Name, @Price);\nEND\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\"><strong>Summary<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This example demonstrates a complete end-to-end implementation of adding a product to the database using an <strong>ASP.NET Core Web API<\/strong>:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Controller (<code>ProductController<\/code>)<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Handles the incoming HTTP POST request and returns appropriate responses.<\/li>\n\n\n\n<li>Uses <strong>FluentValidation<\/strong> to validate input.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Service Layer (<code>ProductService<\/code>)<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Handles <strong>business logic<\/strong> and validation using a validator.<\/li>\n\n\n\n<li>Calls the <strong>repository<\/strong> to save data after validation.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Repository Layer (<code>ProductRepository<\/code>)<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Uses <strong>ADO.NET<\/strong> to interact with the <strong>SQL Server<\/strong> database.<\/li>\n\n\n\n<li>Executes a stored procedure to add the product.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Key Features Implemented<\/strong>:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Validation<\/strong>: Using <strong>FluentValidation<\/strong> to validate the request data.<\/li>\n\n\n\n<li><strong>Error Handling<\/strong>:\n<ul class=\"wp-block-list\">\n<li><strong>ValidationException<\/strong>: Returns <code>400 Bad Request<\/code> with details of validation errors.<\/li>\n\n\n\n<li><strong>General Exception<\/strong>: Returns <code>500 Internal Server Error<\/code> if a database connection or other error occurs.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Layered Architecture<\/strong>: Follows <strong>separation of concerns<\/strong> by splitting responsibilities into <strong>controller<\/strong>, <strong>service<\/strong>, and <strong>repository<\/strong> layers.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Learning Objectives: RESTful Design What is REST? REST (Representational State Transfer) is an architectural style for designing networked applications. RESTful APIs use HTTP methods (GET, POST, PUT, DELETE) to manage resources and are easy to use, scalable, and widely adopted for web services. Key RESTful Concepts: Example of Resource URL: Example: Creating RESTful Endpoints: Real-Life [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"on","ocean_gallery_id":[],"footnotes":""},"categories":[79],"tags":[],"class_list":["post-1980","post","type-post","status-publish","format-standard","hentry","category-dotnet-8","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Building RESTful APIs - Code Notebook<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/\" \/>\n<meta property=\"og:locale\" content=\"he_IL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building RESTful APIs - Code Notebook\" \/>\n<meta property=\"og:description\" content=\"Learning Objectives: RESTful Design What is REST? REST (Representational State Transfer) is an architectural style for designing networked applications. RESTful APIs use HTTP methods (GET, POST, PUT, DELETE) to manage resources and are easy to use, scalable, and widely adopted for web services. Key RESTful Concepts: Example of Resource URL: Example: Creating RESTful Endpoints: Real-Life [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/\" \/>\n<meta property=\"og:site_name\" content=\"Code Notebook\" \/>\n<meta property=\"article:published_time\" content=\"2024-10-31T16:36:19+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-11-01T06:47:02+00:00\" \/>\n<meta name=\"author\" content=\"kerendanino\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u05e0\u05db\u05ea\u05d1 \u05e2\u05dc \u05d9\u05d3\" \/>\n\t<meta name=\"twitter:data1\" content=\"kerendanino\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u05d6\u05de\u05df \u05e7\u05e8\u05d9\u05d0\u05d4 \u05de\u05d5\u05e2\u05e8\u05da\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 \u05d3\u05e7\u05d5\u05ea\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/building-restful-apis\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/building-restful-apis\\\/\"},\"author\":{\"name\":\"kerendanino\",\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/#\\\/schema\\\/person\\\/195dfc625818eadda7903d456890e24c\"},\"headline\":\"Building RESTful APIs\",\"datePublished\":\"2024-10-31T16:36:19+00:00\",\"dateModified\":\"2024-11-01T06:47:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/building-restful-apis\\\/\"},\"wordCount\":1183,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/#organization\"},\"articleSection\":[\"Dotnet 8\"],\"inLanguage\":\"he-IL\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/building-restful-apis\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/building-restful-apis\\\/\",\"url\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/building-restful-apis\\\/\",\"name\":\"Building RESTful APIs - Code Notebook\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/#website\"},\"datePublished\":\"2024-10-31T16:36:19+00:00\",\"dateModified\":\"2024-11-01T06:47:02+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/building-restful-apis\\\/#breadcrumb\"},\"inLanguage\":\"he-IL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/building-restful-apis\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/building-restful-apis\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building RESTful APIs\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/#website\",\"url\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/\",\"name\":\"Code Notebook\",\"description\":\"Easy coding\",\"publisher\":{\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"he-IL\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/#organization\",\"name\":\"Code Notebook\",\"url\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"he-IL\",\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-epic-marketing-05.png\",\"contentUrl\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-epic-marketing-05.png\",\"width\":3626,\"height\":1942,\"caption\":\"Code Notebook\"},\"image\":{\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/#\\\/schema\\\/person\\\/195dfc625818eadda7903d456890e24c\",\"name\":\"kerendanino\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"he-IL\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/285cc9389c66aa46da1e26a474b1e90e9efaf3fa21f1b928cbd63ce5f0e89c63?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/285cc9389c66aa46da1e26a474b1e90e9efaf3fa21f1b928cbd63ce5f0e89c63?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/285cc9389c66aa46da1e26a474b1e90e9efaf3fa21f1b928cbd63ce5f0e89c63?s=96&d=mm&r=g\",\"caption\":\"kerendanino\"},\"url\":\"https:\\\/\\\/epicmarketing.co.il\\\/notebook\\\/author\\\/kerendanino\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Building RESTful APIs - Code Notebook","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/","og_locale":"he_IL","og_type":"article","og_title":"Building RESTful APIs - Code Notebook","og_description":"Learning Objectives: RESTful Design What is REST? REST (Representational State Transfer) is an architectural style for designing networked applications. RESTful APIs use HTTP methods (GET, POST, PUT, DELETE) to manage resources and are easy to use, scalable, and widely adopted for web services. Key RESTful Concepts: Example of Resource URL: Example: Creating RESTful Endpoints: Real-Life [&hellip;]","og_url":"https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/","og_site_name":"Code Notebook","article_published_time":"2024-10-31T16:36:19+00:00","article_modified_time":"2024-11-01T06:47:02+00:00","author":"kerendanino","twitter_card":"summary_large_image","twitter_misc":{"\u05e0\u05db\u05ea\u05d1 \u05e2\u05dc \u05d9\u05d3":"kerendanino","\u05d6\u05de\u05df \u05e7\u05e8\u05d9\u05d0\u05d4 \u05de\u05d5\u05e2\u05e8\u05da":"7 \u05d3\u05e7\u05d5\u05ea"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/#article","isPartOf":{"@id":"https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/"},"author":{"name":"kerendanino","@id":"https:\/\/epicmarketing.co.il\/notebook\/#\/schema\/person\/195dfc625818eadda7903d456890e24c"},"headline":"Building RESTful APIs","datePublished":"2024-10-31T16:36:19+00:00","dateModified":"2024-11-01T06:47:02+00:00","mainEntityOfPage":{"@id":"https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/"},"wordCount":1183,"commentCount":0,"publisher":{"@id":"https:\/\/epicmarketing.co.il\/notebook\/#organization"},"articleSection":["Dotnet 8"],"inLanguage":"he-IL","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/","url":"https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/","name":"Building RESTful APIs - Code Notebook","isPartOf":{"@id":"https:\/\/epicmarketing.co.il\/notebook\/#website"},"datePublished":"2024-10-31T16:36:19+00:00","dateModified":"2024-11-01T06:47:02+00:00","breadcrumb":{"@id":"https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/#breadcrumb"},"inLanguage":"he-IL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/epicmarketing.co.il\/notebook\/building-restful-apis\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/epicmarketing.co.il\/notebook\/"},{"@type":"ListItem","position":2,"name":"Building RESTful APIs"}]},{"@type":"WebSite","@id":"https:\/\/epicmarketing.co.il\/notebook\/#website","url":"https:\/\/epicmarketing.co.il\/notebook\/","name":"Code Notebook","description":"Easy coding","publisher":{"@id":"https:\/\/epicmarketing.co.il\/notebook\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/epicmarketing.co.il\/notebook\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"he-IL"},{"@type":"Organization","@id":"https:\/\/epicmarketing.co.il\/notebook\/#organization","name":"Code Notebook","url":"https:\/\/epicmarketing.co.il\/notebook\/","logo":{"@type":"ImageObject","inLanguage":"he-IL","@id":"https:\/\/epicmarketing.co.il\/notebook\/#\/schema\/logo\/image\/","url":"https:\/\/epicmarketing.co.il\/notebook\/wp-content\/uploads\/2023\/07\/logo-epic-marketing-05.png","contentUrl":"https:\/\/epicmarketing.co.il\/notebook\/wp-content\/uploads\/2023\/07\/logo-epic-marketing-05.png","width":3626,"height":1942,"caption":"Code Notebook"},"image":{"@id":"https:\/\/epicmarketing.co.il\/notebook\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/epicmarketing.co.il\/notebook\/#\/schema\/person\/195dfc625818eadda7903d456890e24c","name":"kerendanino","image":{"@type":"ImageObject","inLanguage":"he-IL","@id":"https:\/\/secure.gravatar.com\/avatar\/285cc9389c66aa46da1e26a474b1e90e9efaf3fa21f1b928cbd63ce5f0e89c63?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/285cc9389c66aa46da1e26a474b1e90e9efaf3fa21f1b928cbd63ce5f0e89c63?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/285cc9389c66aa46da1e26a474b1e90e9efaf3fa21f1b928cbd63ce5f0e89c63?s=96&d=mm&r=g","caption":"kerendanino"},"url":"https:\/\/epicmarketing.co.il\/notebook\/author\/kerendanino\/"}]}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/epicmarketing.co.il\/notebook\/wp-json\/wp\/v2\/posts\/1980","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/epicmarketing.co.il\/notebook\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/epicmarketing.co.il\/notebook\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/epicmarketing.co.il\/notebook\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/epicmarketing.co.il\/notebook\/wp-json\/wp\/v2\/comments?post=1980"}],"version-history":[{"count":4,"href":"https:\/\/epicmarketing.co.il\/notebook\/wp-json\/wp\/v2\/posts\/1980\/revisions"}],"predecessor-version":[{"id":1988,"href":"https:\/\/epicmarketing.co.il\/notebook\/wp-json\/wp\/v2\/posts\/1980\/revisions\/1988"}],"wp:attachment":[{"href":"https:\/\/epicmarketing.co.il\/notebook\/wp-json\/wp\/v2\/media?parent=1980"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/epicmarketing.co.il\/notebook\/wp-json\/wp\/v2\/categories?post=1980"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/epicmarketing.co.il\/notebook\/wp-json\/wp\/v2\/tags?post=1980"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}