{"id":32571,"date":"2025-04-02T15:19:47","date_gmt":"2025-04-02T13:19:47","guid":{"rendered":"https:\/\/www.codemotion.com\/magazine\/?p=32571"},"modified":"2025-04-02T15:19:49","modified_gmt":"2025-04-02T13:19:49","slug":"net-refactoring-series-episode-1-how-to-approach-service-refactoring","status":"publish","type":"post","link":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/","title":{"rendered":".NET Refactoring Series: Episode 1\u200a\u2014\u200aHow to Approach Service Refactoring"},"content":{"rendered":"\n<p>Every developer, sooner or later, faces the challenge of refactoring a project that started as a proof of concept but ended up in production.<\/p>\n\n\n\n<p>For me, this is an exciting task. It gives me the opportunity to learn new things, complain about <em>\u201cwho the hell wrote this code?\u201d<\/em>, and apply my knowledge to make the code cleaner and more maintainable.<\/p>\n\n\n\n<p>At the same time, refactoring can be quite tricky\u2014especially when the project is already in production and <em>\u201cworks fine\u201d<\/em>, but adding new features has become difficult, the service is struggling to scale, and worst of all, there are no tests.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Where we begin<\/h2>\n\n\n\n<p>This series is built around practical examples. You can find the full code on <a href=\"https:\/\/github.com\/giovanni-ferrari\/the-refactoring-series\">GitHub<\/a>.<\/p>\n\n\n\n<p>The <em>OrderService<\/em> from <a href=\"https:\/\/github.com\/giovanni-ferrari\/the-refactoring-series\/tree\/main\/00.initial-version\">Lesson-00<\/a> has several issues. Despite being a small service, the code is already quite intricate. Technical concerns and business logic are not properly separated into clear abstractions, and cognitive complexity has not been considered at all.<\/p>\n\n\n\n<p>But the most alarming issue? There are absolutely no tests\u2014of any kind.<\/p>\n\n\n\n<p>How can you ensure that the <em>OrderService<\/em> will still work the same way after refactoring? Would you take the risk of refactoring, merging the Pull Request, and deploying to production?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The importance of Tests<\/h2>\n\n\n\n<p>Tests are the key to confidence. A well-designed test suite allows you to develop new features or refactor existing code with the assurance that you can always run the tests to verify whether the code still behaves as expected.<\/p>\n\n\n\n<p>In fact, a failing test can sometimes be reassuring\u2014it means the tests are doing their job, catching issues before they reach production, and giving you time to fix them.<\/p>\n\n\n\n<p>Now that we understand the importance of tests, we should already know the first step before refactoring <em>OrderService<\/em>: write tests! But what kind of tests?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Unit tests<\/h2>\n\n\n\n<p>Unit tests verify the behavior of individual components or <em>units<\/em> of code in isolation. In object-oriented programming, this usually means testing a single class or method. They\u2019re invaluable during development\u2014they catch bugs early, document how the code works, and make refactoring safer.<\/p>\n\n\n\n<p>Unit tests can also be used with <strong>Test-Driven Development (TDD)<\/strong>. The idea is simple:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Write a test before writing any code.<\/li>\n\n\n\n<li>Run the test\u2014it should fail because the functionality doesn\u2019t exist yet.<\/li>\n\n\n\n<li>Implement the minimal code needed to make the test pass.<\/li>\n\n\n\n<li>Refactor if necessary, then repeat.<\/li>\n<\/ol>\n\n\n\n<p>In TDD, even a compilation error counts as a failure. For example, if you\u2019re testing a class named OrderController, your first test will fail immediately because the class doesn\u2019t exist yet. This forces you to define it, guiding the development process step by step.<\/p>\n\n\n\n<p><strong>Why use unit tests?<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Run tests fast and provide immediate feedback<\/li>\n\n\n\n<li>Pinpoint exactly where failures occur<\/li>\n\n\n\n<li>Serve as documentation for expected behavior<\/li>\n\n\n\n<li>Make refactoring safer by catching regressions<\/li>\n<\/ul>\n\n\n\n<p>However, unit tests can become a burden when doing major refactoring. Since they\u2019re tightly coupled to implementation details, you might spend more time fixing tests than improving the actual code. That\u2019s why, for this refactoring, we\u2019ll take a different approach.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Integration tests<\/h2>\n\n\n\n<p>Integration tests verify the behavior of an entire service, including its interactions with external components such as databases, service buses, and distributed caches.<\/p>\n\n\n\n<p>A common example is, when developing a .NET Web API, an integration test ensures that the entire pipeline, from the HTTP request to the controller, including AspNet middleware, works correctly.<\/p>\n\n\n\n<p>In our case, <a href=\"https:\/\/github.com\/giovanni-ferrari\/the-refactoring-series\/tree\/main\/01.prepare-for-refactoring\/src\/OrderService.Api\">OrderService.Api<\/a> requires a significant refactor. As mentioned earlier, writing unit tests in this scenario could be more of a burden than a benefit. However, since <em>OrderService.Api<\/em> is already in production, we <strong>must<\/strong> ensure that its external behavior, particularly its public contracts (REST APIs), remains unchanged during the refactoring process.<\/p>\n\n\n\n<p>This is where <strong>integration tests<\/strong> excel. Rather than testing internal implementation details, we test <em>OrderService.Api<\/em> through its public contracts, ensuring it behaves correctly from the outside. The process can be summarized as follows:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Invoke a REST API endpoint in <em>OrderService.Api<\/em>.<\/li>\n\n\n\n<li>Verify the <a href=\"https:\/\/www.codemotion.com\/magazine\/cybersecurity\/5-tips-for-boosting-api-security\/\">API <\/a>response.<\/li>\n\n\n\n<li>Validate any side effects, such as checking if an order was persisted in the database after making a POST \/api\/order request.<\/li>\n<\/ol>\n\n\n\n<p>With integration tests, we treat <em>OrderService.Api<\/em> as a <strong>black box<\/strong>, focusing solely on its external behavior. This allows us to confidently refactor the internal implementation while ensuring that the service continues to function as expected.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Essential .NET libraries for Integration Tests<\/h2>\n\n\n\n<p>Here the libraries used in the OrderService.Api example to write <a href=\"https:\/\/github.com\/giovanni-ferrari\/the-refactoring-series\/tree\/main\/01.prepare-for-refactoring\/test\/OrderService.Api.Integration.Tests\">OrderService.Api.Integration.Tests<\/a><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/dotnet.testcontainers.org\">Test Containers for .NET<\/a> : used to startup containers with services required for the integration test &#8211; in our case Sql Server<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/AutoFixture\/AutoFixture\">Autofixture<\/a> : helpfull to create test data<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/jbogard\/Respawn\">Respawn<\/a> : used to reset the database content at each test<\/li>\n\n\n\n<li><a href=\"https:\/\/fluentassertions.com\">Fluent Assertions<\/a> : provides fluent methods to assert test results<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Setup test environment<\/h2>\n\n\n\n<p>Using <a href=\"https:\/\/dotnet.testcontainers.org\/\">TestContainers for .NET<\/a>, we can spin up a lightweight test environment for our integration tests.<\/p>\n\n\n\n<p>Our integration tests are built using <a href=\"https:\/\/xunit.net\/\">XUnit<\/a>, which provides a mechanism to share context between tests: <a href=\"https:\/\/xunit.net\/docs\/shared-context\">Fixtures<\/a>. In this case, the shared context is the test environment itself.<\/p>\n\n\n\n<p>To achieve this, we create a <strong>Class Fixture<\/strong> that ensures all test cases in a class use the same test environment. This fixture will:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Start all required containers<\/li>\n\n\n\n<li>Boot up the web service, which is our <em>System Under Test (SUT)<\/em><\/li>\n\n\n\n<li>Provide reusable resources like HTTP clients and database connections<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>Integration Test Fixture<\/strong><\/p>\n\n\n\n<p>The IntegrationTestFixture manages the lifecycle of the test environment. It initializes the <strong>SQL Server container<\/strong> and the <strong>OrderService API<\/strong> instance.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">namespace OrderService.Api.Integration.Tests.Fixtures;\n\npublic sealed class IntegrationTestFixture : IAsyncLifetime\n{\n    public OrderServiceFixture? OrderServiceFixture { get; private set; }\n    public HttpClient? Client { get; private set; }\n    public SqlServerFixture SqlServerFixture { get; }\n    \n    \n    public IntegrationTestFixture()\n    {\n        SqlServerFixture = new SqlServerFixture();\n    }\n\n    public async Task InitializeAsync()\n    {\n        await SqlServerFixture.InitializeAsync();\n        OrderServiceFixture = new OrderServiceFixture(SqlServerFixture.GetConnectionString());  \n        Client = OrderServiceFixture.CreateClient();\n    }\n\n    public async Task DisposeAsync()\n    {\n        await SqlServerFixture.DisposeAsync();\n        await (OrderServiceFixture?.DisposeAsync() ?? ValueTask.CompletedTask);\n        Client?.Dispose();\n    }\n}\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>Bootstrapping the API for Testing<\/strong><\/p>\n\n\n\n<p>The OrderServiceFixture is responsible for launching the API in memory using <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/test\/integration-tests?view=aspnetcore-9.0\">WebApplicationFactory<\/a>. This is a built-in .NET feature that enables full end-to-end testing without needing a live web server.<\/p>\n\n\n\n<p>One of its key benefits is that it allows us to <strong>override configurations<\/strong>\u2014for example, injecting a database connection string from our SQL Server test container.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">namespace OrderService.Api.Integration.Tests.Fixtures;\n\npublic class OrderServiceFixture : WebApplicationFactory<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Program<\/span>&gt;<\/span>\n{\n    private readonly string connectionString;\n\n    public OrderServiceFixture(string connectionString)\n    {\n        this.connectionString = connectionString;\n    }\n    protected override void ConfigureWebHost(IWebHostBuilder builder)\n    {\n        builder.ConfigureAppConfiguration((context, config) =&gt;\n        {\n            config.AddInMemoryCollection(new Dictionary<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">string,<\/span> <span class=\"hljs-attr\">string<\/span>?&gt;<\/span>\n            {\n                &#91;\"ConnectionStrings:DefaultConnection\"] = connectionString\n            });\n        });\n        base.ConfigureWebHost(builder);\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>Sql Server Container instance<\/strong><\/p>\n\n\n\n<p>Sql Server is started in a container instance using <em>Test Containers for .NET<\/em><\/p>\n\n\n\n<p>In short, the container is built starting from official image and the <em>SqlServerFixture<\/em> offers methods to startup and shutdown the container, implementing <em>IAsyncLifetime<\/em> interface<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">\/\/\/ <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">summary<\/span>&gt;<\/span>\n\/\/\/ Represents a fixture that provides a SQL Server instance for testing.\n\/\/\/ Startup SQL Server docker container, create a database, and run migrations.\n\/\/\/ <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">summary<\/span>&gt;<\/span>\npublic class SqlServerFixture : IAsyncLifetime\n{\n    private readonly MsSqlContainer _sqlContainer;\n    private const string DATABASE_PASSWORD = \"yourStrong(!)Password\";\n    private const string DATABASE_IMAGE = \"mcr.microsoft.com\/mssql\/server:2022-latest\";\n    private const string DATABASE_NAME = \"OrderService\";\n    private const string DATABASE_CREATE_SCRIPT = \"order-service.sql\";\n\n    public SqlServerFixture()\n    {\n        _sqlContainer = new MsSqlBuilder()\n            .WithImage(DATABASE_IMAGE)\n            .WithPassword(DATABASE_PASSWORD)\n            .Build();\n    }\n    \n    public string GetConnectionString()\n    {\n        SqlConnectionStringBuilder builder = new(_sqlContainer.GetConnectionString());\n        builder.InitialCatalog = DATABASE_NAME;\n        return builder.ConnectionString;\n    }\n\n    public async Task InitializeAsync()\n    {\n        await _sqlContainer.StartAsync();\n        await InitializeDatabaseAsync();\n    }\n\n    private async Task InitializeDatabaseAsync()\n    {\n        \/\/Create database, schema and tables \n    }\n\n    public async Task DisposeAsync()\n    {\n        await _sqlContainer.StopAsync();\n        await _sqlContainer.DisposeAsync();\n    }\n}\n\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Implement Integration Tests<\/h2>\n\n\n\n<p>Now, let\u2019s implement the integration tests. Our test class requires the <em>IntegrationTestFixture<\/em>, which is responsible for setting up the test environment. Additionally, since the tests persist data in the database, we use the <em>Respawn<\/em> library to reset the database after each test execution.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">public class OrderControllerIntegrationTests : IClassFixture<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">IntegrationTestFixture<\/span>&gt;<\/span>, IAsyncLifetime\n{\n    private readonly IntegrationTestFixture fixture;\n    private Respawner? respawner;\n    private readonly Fixture autoFixture = new();\n\n    public OrderControllerIntegrationTests(IntegrationTestFixture fixture)\n    {\n        this.fixture = fixture;\n    }\n    public async Task DisposeAsync()\n    {\n        await respawner!.ResetAsync(fixture.SqlServerFixture.GetConnectionString());\n    }\n\n    public async Task InitializeAsync()\n    {\n        respawner = await Respawner.CreateAsync(fixture.SqlServerFixture.GetConnectionString(), new RespawnerOptions(){\n            TablesToInclude = &#91;\"Orders\"],\n            SchemasToInclude = &#91;\"Order\"]\n        });\n    }\n    \n    \/\/Tests\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Next, the tests verify all the endpoints implemented in <em>OrderController<\/em>, aiming to cover all possible cases.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">&#91;Fact]\npublic <span class=\"hljs-keyword\">async<\/span> Task GetOrders_WhenOrdersListIsEmpty_ThenReturnsOkWithEmptyResult()\n{\n    <span class=\"hljs-comment\">\/\/ Arrange<\/span>\n    <span class=\"hljs-keyword\">var<\/span> response = <span class=\"hljs-keyword\">await<\/span> fixture.Client!.GetAsync(<span class=\"hljs-string\">\"\/api\/order\"<\/span>);\n    response.EnsureSuccessStatusCode();\n\n    <span class=\"hljs-comment\">\/\/ Act<\/span>\n    <span class=\"hljs-keyword\">var<\/span> orders = <span class=\"hljs-keyword\">await<\/span> response.Content.ReadFromJsonAsync&lt;List&lt;Order&gt;&gt;();\n\n    <span class=\"hljs-comment\">\/\/ Assert<\/span>\n    orders.Should().NotBeNull();\n    orders.Should().BeEmpty();\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Conclusions<\/h2>\n\n\n\n<p>Refactoring a service that is already in production can be challenging\u2014and without proper testing, even risky.<\/p>\n\n\n\n<p>Writing tests might seem like a waste of time at first. Instead of jumping straight into developing a new feature or refactoring code, you have to invest significant effort in creating tests. But this effort is not wasted; it\u2019s an investment. Once tests are in place, every future change becomes faster and safer, allowing for smooth deployments through CI\/CD pipelines.<\/p>\n\n\n\n<p>If you ever feel like it\u2019s too late to start writing tests for a production service, remember a common piece of financial advice: <em>The best time to start investing was yesterday. The second-best time is now.<\/em><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Every developer, sooner or later, faces the challenge of refactoring a project that started as a proof of concept but ended up in production. For me, this is an exciting task. It gives me the opportunity to learn new things, complain about \u201cwho the hell wrote this code?\u201d, and apply my knowledge to make the&#8230; <a class=\"more-link\" href=\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/\">Read more<\/a><\/p>\n","protected":false},"author":319,"featured_media":32610,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_uag_custom_page_level_css":"","_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[36],"tags":[],"collections":[],"class_list":{"0":"post-32571","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-backend","8":"entry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How to Approach Service Refactoring<\/title>\n<meta name=\"description\" content=\"Learn about service refactoring and how to tackle the challenge of transforming a proof of concept into a scalable and maintainable production project.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\".NET Refactoring Series: Episode 1\u200a\u2014\u200aHow to Approach Service Refactoring\" \/>\n<meta property=\"og:description\" content=\"Learn about service refactoring and how to tackle the challenge of transforming a proof of concept into a scalable and maintainable production project.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/\" \/>\n<meta property=\"og:site_name\" content=\"Codemotion Magazine\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Codemotion.Italy\/\" \/>\n<meta property=\"article:published_time\" content=\"2025-04-02T13:19:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-02T13:19:49+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1792\" \/>\n\t<meta property=\"og:image:height\" content=\"1024\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"giovanni-ferrari\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:site\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"giovanni-ferrari\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/\"},\"author\":{\"name\":\"giovanni-ferrari\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/901b08ffda8fc6b076adb9d2cb445f8e\"},\"headline\":\".NET Refactoring Series: Episode 1\u200a\u2014\u200aHow to Approach Service Refactoring\",\"datePublished\":\"2025-04-02T13:19:47+00:00\",\"dateModified\":\"2025-04-02T13:19:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/\"},\"wordCount\":1200,\"publisher\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi.webp\",\"articleSection\":[\"Backend\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/\",\"name\":\"How to Approach Service Refactoring\",\"isPartOf\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi.webp\",\"datePublished\":\"2025-04-02T13:19:47+00:00\",\"dateModified\":\"2025-04-02T13:19:49+00:00\",\"description\":\"Learn about service refactoring and how to tackle the challenge of transforming a proof of concept into a scalable and maintainable production project.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#primaryimage\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi.webp\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi.webp\",\"width\":1792,\"height\":1024},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Backend\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/backend\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\".NET Refactoring Series: Episode 1\u200a\u2014\u200aHow to Approach Service Refactoring\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#website\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/\",\"name\":\"Codemotion Magazine\",\"description\":\"We code the future. Together\",\"publisher\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\",\"name\":\"Codemotion\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png\",\"width\":225,\"height\":225,\"caption\":\"Codemotion\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Codemotion.Italy\/\",\"https:\/\/x.com\/CodemotionIT\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/901b08ffda8fc6b076adb9d2cb445f8e\",\"name\":\"giovanni-ferrari\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e414c71673b00987be912bf844aa152549421dd4e0f6390e53f414cc666371aa?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e414c71673b00987be912bf844aa152549421dd4e0f6390e53f414cc666371aa?s=96&d=mm&r=g\",\"caption\":\"giovanni-ferrari\"},\"description\":\"Expert in Industry 4.0, Manufacturing Execution Systems (MES) for the Automotive Industry, IoT, and Cloud Architecture. Passionate about technology, creativity, and problem-solving, I thrive on designing smart and efficient solutions to complex challenges.\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/author\/giovanni-ferrari\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How to Approach Service Refactoring","description":"Learn about service refactoring and how to tackle the challenge of transforming a proof of concept into a scalable and maintainable production project.","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:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/","og_locale":"en_US","og_type":"article","og_title":".NET Refactoring Series: Episode 1\u200a\u2014\u200aHow to Approach Service Refactoring","og_description":"Learn about service refactoring and how to tackle the challenge of transforming a proof of concept into a scalable and maintainable production project.","og_url":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/","og_site_name":"Codemotion Magazine","article_publisher":"https:\/\/www.facebook.com\/Codemotion.Italy\/","article_published_time":"2025-04-02T13:19:47+00:00","article_modified_time":"2025-04-02T13:19:49+00:00","og_image":[{"width":1792,"height":1024,"url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi.webp","type":"image\/webp"}],"author":"giovanni-ferrari","twitter_card":"summary_large_image","twitter_creator":"@CodemotionIT","twitter_site":"@CodemotionIT","twitter_misc":{"Written by":"giovanni-ferrari","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#article","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/"},"author":{"name":"giovanni-ferrari","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/901b08ffda8fc6b076adb9d2cb445f8e"},"headline":".NET Refactoring Series: Episode 1\u200a\u2014\u200aHow to Approach Service Refactoring","datePublished":"2025-04-02T13:19:47+00:00","dateModified":"2025-04-02T13:19:49+00:00","mainEntityOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/"},"wordCount":1200,"publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi.webp","articleSection":["Backend"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/","url":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/","name":"How to Approach Service Refactoring","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#primaryimage"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi.webp","datePublished":"2025-04-02T13:19:47+00:00","dateModified":"2025-04-02T13:19:49+00:00","description":"Learn about service refactoring and how to tackle the challenge of transforming a proof of concept into a scalable and maintainable production project.","breadcrumb":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#primaryimage","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi.webp","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi.webp","width":1792,"height":1024},{"@type":"BreadcrumbList","@id":"https:\/\/www.codemotion.com\/magazine\/backend\/net-refactoring-series-episode-1-how-to-approach-service-refactoring\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.codemotion.com\/magazine\/"},{"@type":"ListItem","position":2,"name":"Backend","item":"https:\/\/www.codemotion.com\/magazine\/backend\/"},{"@type":"ListItem","position":3,"name":".NET Refactoring Series: Episode 1\u200a\u2014\u200aHow to Approach Service Refactoring"}]},{"@type":"WebSite","@id":"https:\/\/www.codemotion.com\/magazine\/#website","url":"https:\/\/www.codemotion.com\/magazine\/","name":"Codemotion Magazine","description":"We code the future. Together","publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.codemotion.com\/magazine\/#organization","name":"Codemotion","url":"https:\/\/www.codemotion.com\/magazine\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","width":225,"height":225,"caption":"Codemotion"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Codemotion.Italy\/","https:\/\/x.com\/CodemotionIT"]},{"@type":"Person","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/901b08ffda8fc6b076adb9d2cb445f8e","name":"giovanni-ferrari","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e414c71673b00987be912bf844aa152549421dd4e0f6390e53f414cc666371aa?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e414c71673b00987be912bf844aa152549421dd4e0f6390e53f414cc666371aa?s=96&d=mm&r=g","caption":"giovanni-ferrari"},"description":"Expert in Industry 4.0, Manufacturing Execution Systems (MES) for the Automotive Industry, IoT, and Cloud Architecture. Passionate about technology, creativity, and problem-solving, I thrive on designing smart and efficient solutions to complex challenges.","url":"https:\/\/www.codemotion.com\/magazine\/author\/giovanni-ferrari\/"}]}},"featured_image_src":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-600x400.webp","featured_image_src_square":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-600x600.webp","author_info":{"display_name":"giovanni-ferrari","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/giovanni-ferrari\/"},"uagb_featured_image_src":{"full":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi.webp",1792,1024,false],"thumbnail":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-150x150.webp",150,150,true],"medium":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-300x171.webp",300,171,true],"medium_large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-768x439.webp",768,439,true],"large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-1024x585.webp",1024,585,true],"1536x1536":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-1536x878.webp",1536,878,true],"2048x2048":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi.webp",1792,1024,false],"small-home-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-100x100.webp",100,100,true],"sidebar-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-180x128.webp",180,128,true],"genesis-singular-images":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-896x504.webp",896,504,true],"archive-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-400x225.webp",400,225,true],"gb-block-post-grid-landscape":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-600x400.webp",600,400,true],"gb-block-post-grid-square":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/04\/DALL\u00b7E-2025-04-02-15.15.04-A-modern-clean-and-professional-horizontal-banner-image-for-a-tech-article.-The-scene-includes-abstract-representations-of-software-architecture-mi-600x600.webp",600,600,true]},"uagb_author_info":{"display_name":"giovanni-ferrari","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/giovanni-ferrari\/"},"uagb_comment_info":0,"uagb_excerpt":"Every developer, sooner or later, faces the challenge of refactoring a project that started as a proof of concept but ended up in production. For me, this is an exciting task. It gives me the opportunity to learn new things, complain about \u201cwho the hell wrote this code?\u201d, and apply my knowledge to make the&#8230;&hellip;","lang":"en","_links":{"self":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/32571","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/users\/319"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/comments?post=32571"}],"version-history":[{"count":2,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/32571\/revisions"}],"predecessor-version":[{"id":32615,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/32571\/revisions\/32615"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media\/32610"}],"wp:attachment":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media?parent=32571"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/categories?post=32571"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/tags?post=32571"},{"taxonomy":"collections","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/collections?post=32571"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}