{"id":3824,"date":"2025-12-24T10:00:51","date_gmt":"2025-12-24T15:00:51","guid":{"rendered":"https:\/\/www.mymiller.name\/wordpress\/?p=3824"},"modified":"2025-12-24T10:00:51","modified_gmt":"2025-12-24T15:00:51","slug":"customizing-reads-triggering-events-on-get-requests-with-spring-data-rest","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/spring_rest\/customizing-reads-triggering-events-on-get-requests-with-spring-data-rest\/","title":{"rendered":"Customizing Reads: Triggering Events on GET Requests with Spring Data REST"},"content":{"rendered":"\n<div class=\"wp-block-jetpack-markdown\"><p>While Spring Data REST excels at generating CRUD endpoints, the standard life cycle events we\u2019ve discussed primarily revolve around data modification (Create, Update, Delete). You might encounter scenarios where you need to trigger specific actions or logic <em>when an entity is read<\/em> via a <code>GET<\/code> request.<\/p>\n<p>Out of the box, Spring Data REST doesn\u2019t directly publish the standard <code>BeforeLoadEvent<\/code> or <code>AfterLoadEvent<\/code> for <code>GET<\/code> requests in the same way it does for persistence operations. However, you can achieve this by leveraging Spring Data REST\u2019s customization capabilities and Spring\u2019s event publishing mechanism.<\/p>\n<p>This article will explore different approaches to trigger custom events when entities are retrieved through Spring Data REST <code>GET<\/code> endpoints.<\/p>\n<p><strong>Understanding the Challenge<\/strong><\/p>\n<p>The core reason why standard Spring Data Commons persistence events aren\u2019t triggered on <code>GET<\/code> requests is that these events are tied to the entity management lifecycle (persisting, updating, deleting). Reading data is a separate operation.<\/p>\n<p>Therefore, we need to find alternative ways to intercept the read operation and publish our custom events. Here are a few strategies:<\/p>\n<p><strong>1. Using <code>@RepositoryEventHandler<\/code><\/strong><\/p>\n<p>Spring Data REST provides the <code>@RepositoryEventHandler<\/code> annotation, which allows you to intercept repository method invocations. We can use this to trigger an event after a successful retrieval.<\/p>\n<ul>\n<li>\n<p><strong>Create your custom event:<\/strong><\/p>\n<pre><code class=\"language-java\">import org.springframework.context.ApplicationEvent;\n\npublic class ProductReadEvent extends ApplicationEvent {\n    private final Product product;\n\n    public ProductReadEvent(Object source, Product product) {\n        super(source);\n        this.product = product;\n    }\n\n    public Product getProduct() {\n        return product;\n    }\n}\n<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>Create a Repository Event Handler:<\/strong><\/p>\n<pre><code class=\"language-java\">import org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.context.ApplicationEventPublisher;\nimport org.springframework.data.rest.core.annotation.HandleAfterGet;\nimport org.springframework.data.rest.core.annotation.RepositoryEventHandler;\n\n@RepositoryEventHandler(Product.class)\npublic class ProductReadEventHandler {\n\n    @Autowired\n    private ApplicationEventPublisher publisher;\n\n    @HandleAfterGet\n    public void handleAfterGet(Product product) {\n        publisher.publishEvent(new ProductReadEvent(this, product));\n        System.out.println(&quot;Product read event triggered for product ID: &quot; + product.getId());\n        \/\/ Perform any other actions after a product is read\n    }\n}\n<\/code><\/pre>\n<ul>\n<li><code>@RepositoryEventHandler(Product.class)<\/code>: This annotation indicates that this handler is specific to the <code>Product<\/code> entity.<\/li>\n<li><code>@Autowired private ApplicationEventPublisher publisher;<\/code>: We inject the <code>ApplicationEventPublisher<\/code> to publish our custom event.<\/li>\n<li><code>@HandleAfterGet<\/code>: This annotation marks the <code>handleAfterGet<\/code> method to be invoked <em>after<\/em> an entity of type <code>Product<\/code> is successfully retrieved by a <code>GET<\/code> request to <code>\/products\/{id}<\/code>. The retrieved <code>Product<\/code> instance is passed as an argument.<\/li>\n<li>Inside the method, we create and publish our <code>ProductReadEvent<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>Create an Event Listener:<\/strong><\/p>\n<pre><code class=\"language-java\">import org.springframework.context.event.EventListener;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class ProductReadEventListener {\n\n    @EventListener\n    public void handleProductReadEvent(ProductReadEvent event) {\n        Product readProduct = event.getProduct();\n        System.out.println(&quot;Listener received ProductReadEvent for product: &quot; + readProduct.getName());\n        \/\/ Perform actions based on the read event (e.g., logging access)\n    }\n}\n<\/code><\/pre>\n<\/li>\n<\/ul>\n<p><strong>2. Using a Custom Controller<\/strong><\/p>\n<p>For more control over the read operation and the event triggering, you can create a custom Spring MVC controller that handles the retrieval of your entity. This bypasses the default Spring Data REST handling for that specific endpoint.<\/p>\n<ul>\n<li>\n<p><strong>Create a custom controller:<\/strong><\/p>\n<pre><code class=\"language-java\">import org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.context.ApplicationEventPublisher;\nimport org.springframework.data.rest.webmvc.RepositoryRestController;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PathVariable;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\n@RepositoryRestController\npublic class CustomProductController {\n\n    @Autowired\n    private ProductRepository productRepository;\n\n    @Autowired\n    private ApplicationEventPublisher publisher;\n\n    @GetMapping(&quot;\/products\/{id}\/read-event&quot;) \/\/ Custom endpoint\n    public @ResponseBody ResponseEntity&lt;?&gt; getProductAndTriggerEvent(@PathVariable Long id) {\n        return productRepository.findById(id)\n                .map(product -&gt; {\n                    publisher.publishEvent(new ProductReadEvent(this, product));\n                    System.out.println(&quot;Product read event triggered via custom controller for ID: &quot; + id);\n                    return ResponseEntity.ok(product);\n                })\n                .orElse(ResponseEntity.notFound().build());\n    }\n}\n<\/code><\/pre>\n<ul>\n<li><code>@RepositoryRestController<\/code>: This annotation is used for controllers that handle operations on Spring Data REST managed repositories.<\/li>\n<li>We inject the <code>ProductRepository<\/code> to fetch the entity.<\/li>\n<li>We define a custom endpoint <code>\/products\/{id}\/read-event<\/code>.<\/li>\n<li>Inside the method, we retrieve the product, publish our <code>ProductReadEvent<\/code>, and then return the product in the response.<\/li>\n<\/ul>\n<p><strong>Note:<\/strong> This approach requires you to define a custom endpoint. The default <code>\/products\/{id}<\/code> endpoint will still function without triggering this event. If you want to override the default behavior, you would need to adjust the <code>@GetMapping<\/code> on your custom controller to <code>\/products\/{id}<\/code>. However, this might lead to unexpected behavior with other Spring Data REST features for that endpoint.<\/p>\n<\/li>\n<\/ul>\n<p><strong>3. Intercepting Repository Methods with AOP (Aspect-Oriented Programming)<\/strong><\/p>\n<p>You could use AOP to intercept the execution of your repository\u2019s <code>findById()<\/code> method (or other read methods) and publish an event after it returns successfully.<\/p>\n<ul>\n<li>\n<p><strong>Create an Aspect:<\/strong><\/p>\n<pre><code class=\"language-java\">import org.aspectj.lang.annotation.AfterReturning;\nimport org.aspectj.lang.annotation.Aspect;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.context.ApplicationEventPublisher;\nimport org.springframework.stereotype.Component;\n\n@Aspect\n@Component\npublic class ReadEventAspect {\n\n    @Autowired\n    private ApplicationEventPublisher publisher;\n\n    @AfterReturning(pointcut = &quot;execution(* com.example.repository.ProductRepository.findById(..))&quot;, returning = &quot;result&quot;)\n    public void afterProductRead(Object result) {\n        if (result instanceof java.util.Optional) {\n            ((java.util.Optional&lt;?&gt;) result).ifPresent(product -&gt; {\n                if (product instanceof Product) {\n                    publisher.publishEvent(new ProductReadEvent(this, (Product) product));\n                    System.out.println(&quot;Product read event triggered via AOP for product: &quot; + ((Product) product).getId());\n                }\n            });\n        }\n    }\n}\n<\/code><\/pre>\n<ul>\n<li><code>@Aspect<\/code> and <code>@Component<\/code>: Mark this class as an Aspect and a Spring-managed component.<\/li>\n<li><code>@AfterReturning<\/code>: This advice runs after the <code>findById()<\/code> method of <code>ProductRepository<\/code> returns successfully.<\/li>\n<li><code>pointcut<\/code>: Specifies the method to intercept. Adjust the package and class name accordingly.<\/li>\n<li><code>returning = &quot;result&quot;<\/code>: Binds the return value of the intercepted method to the <code>result<\/code> parameter.<\/li>\n<li>We check if the result is an <code>Optional&lt;Product&gt;<\/code> and, if present, publish the <code>ProductReadEvent<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><strong>Choosing the Right Approach<\/strong><\/p>\n<ul>\n<li><strong><code>@RepositoryEventHandler (@HandleAfterGet)<\/code>:<\/strong> This is the most straightforward and idiomatic way to trigger events specifically after a Spring Data REST <code>GET<\/code> request for a single item. It\u2019s tightly coupled with the REST layer.<\/li>\n<li><strong>Custom Controller:<\/strong> Provides the most flexibility if you need to perform additional logic or customize the endpoint for triggering the read event. However, it involves more manual controller code.<\/li>\n<li><strong>AOP:<\/strong> Offers a more decoupled way to intercept repository method calls, regardless of how they are invoked (via REST or other services). This can be useful if you want to trigger read events in other parts of your application as well. However, AOP can be more complex to understand and debug.<\/li>\n<\/ul>\n<p><strong>Considerations<\/strong><\/p>\n<ul>\n<li><strong>Performance:<\/strong> Be mindful of the operations you perform in your event listeners. Long-running tasks could impact the response time of your <code>GET<\/code> requests. Consider asynchronous processing for time-consuming operations.<\/li>\n<li><strong>Context:<\/strong> Ensure your event contains enough context (e.g., the retrieved entity, user information if available) for your listeners to perform their tasks effectively.<\/li>\n<li><strong>Idempotency:<\/strong> If the actions triggered by your read event are not idempotent, be cautious about scenarios where a <code>GET<\/code> request might be retried.<\/li>\n<\/ul>\n<p><strong>Conclusion<\/strong><\/p>\n<p>While Spring Data REST doesn\u2019t provide built-in events for <code>GET<\/code> requests, you can effectively trigger custom events using <code>@RepositoryEventHandler<\/code>, custom controllers, or AOP. The <code>@RepositoryEventHandler<\/code> with <code>@HandleAfterGet<\/code> is generally the most aligned with Spring Data REST\u2019s philosophy for handling REST-specific events. Choose the approach that best suits your needs in terms of coupling, control, and the scope of where you want to trigger these read-related actions. Remember to design your events and listeners carefully to ensure performance and maintainability.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":3519,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_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,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[447],"tags":[],"series":[],"class_list":["post-3824","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-spring_rest"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/05\/ai-generated-8041774_640.jpg?fit=640%2C479&ssl=1","jetpack-related-posts":[{"id":3822,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_rest\/beyond-basic-crud-mapping-life-cycle-event-methods-to-spring-data-rest-operations\/","url_meta":{"origin":3824,"position":0},"title":"Beyond Basic CRUD: Mapping Life Cycle Event Methods to Spring Data REST Operations","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Spring Data REST elegantly exposes your JPA entities as RESTful resources, handling the underlying Create, Retrieve, Update, and Delete (CRUD) operations. But how do the life cycle events we discussed earlier align with these API interactions? Understanding this mapping is crucial for effectively implementing custom logic at the right moments.\u2026","rel":"","context":"In &quot;Spring Rest&quot;","block_context":{"text":"Spring Rest","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_rest\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/cpu-8661093_640.jpg?fit=640%2C640&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/cpu-8661093_640.jpg?fit=640%2C640&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/cpu-8661093_640.jpg?fit=640%2C640&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3826,"url":"https:\/\/www.mymiller.name\/wordpress\/spring-gateway\/resilient-gateways-implementing-circuit-breakers-for-spring-data-rest-services-with-spring-cloud-gateway\/","url_meta":{"origin":3824,"position":1},"title":"Resilient Gateways: Implementing Circuit Breakers for Spring Data REST Services with Spring Cloud Gateway","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"In a microservice architecture, services inevitably encounter transient failures \u2013 network hiccups, temporary overload, or slow responses from dependencies. Without proper handling, these failures can cascade, leading to a degraded user experience and even system-wide outages. This is where the circuit breaker pattern comes into play, providing a mechanism to\u2026","rel":"","context":"In &quot;Spring Gateway&quot;","block_context":{"text":"Spring Gateway","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring-gateway\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8314612_640.jpg?fit=640%2C480&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8314612_640.jpg?fit=640%2C480&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8314612_640.jpg?fit=640%2C480&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3568,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_rest\/spring-data-rest-simplify-restful-api-development-2\/","url_meta":{"origin":3824,"position":2},"title":"Spring Data REST: Simplify RESTful API Development","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Spring Data REST is a Spring module that automatically creates RESTful APIs for Spring Data repositories. It eliminates boilerplate code, allowing you to focus on your application\u2019s core logic. Benefits: Reduced Boilerplate: No need to write controllers for CRUD operations. Hypermedia-Driven: APIs are discoverable through links (HAL). Customization: Fine-tune the\u2026","rel":"","context":"In &quot;Spring Rest&quot;","block_context":{"text":"Spring Rest","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_rest\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/network-3152677_640.jpg?fit=640%2C427&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/network-3152677_640.jpg?fit=640%2C427&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/network-3152677_640.jpg?fit=640%2C427&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3553,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_databases\/spring-data-rest-simplify-restful-api-development\/","url_meta":{"origin":3824,"position":3},"title":"Spring Data REST: Simplify RESTful API Development","author":"Jeffery Miller","date":"September 22, 2025","format":false,"excerpt":"Spring Data REST: Simplify RESTful API Development What is Spring Data REST? Spring Data REST is a Spring module that automatically creates RESTful APIs for Spring Data repositories. It eliminates boilerplate code, allowing you to focus on your application\u2019s core logic. Benefits: Reduced Boilerplate: No need to write controllers for\u2026","rel":"","context":"In &quot;Spring Databases&quot;","block_context":{"text":"Spring Databases","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_databases\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/desk-593327_1280.jpg?fit=1200%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/desk-593327_1280.jpg?fit=1200%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/desk-593327_1280.jpg?fit=1200%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/desk-593327_1280.jpg?fit=1200%2C800&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/desk-593327_1280.jpg?fit=1200%2C800&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3928,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_databases\/%f0%9f%92%a1-implementing-cqrs-with-spring-boot-and-kafka\/","url_meta":{"origin":3824,"position":4},"title":"\ud83d\udca1 Implementing CQRS with Spring Boot and Kafka","author":"Jeffery Miller","date":"November 21, 2025","format":false,"excerpt":"As a software architect, I constantly look for patterns that enhance the scalability and maintainability of microservices. The Command Query Responsibility Segregation (CQRS) pattern is a powerful tool for this, especially when coupled with event-driven architecture (EDA) using Apache Kafka. CQRS separates the application into two distinct models: one for\u2026","rel":"","context":"In &quot;Spring Databases&quot;","block_context":{"text":"Spring Databases","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_databases\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/11\/data-2899902_1280.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/11\/data-2899902_1280.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/11\/data-2899902_1280.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/11\/data-2899902_1280.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/11\/data-2899902_1280.avif 3x"},"classes":[]},{"id":3834,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_rest\/documenting-your-datas-reach-generating-api-docs-for-spring-data-rest\/","url_meta":{"origin":3824,"position":5},"title":"Documenting Your Data&#8217;s Reach: Generating API Docs for Spring Data REST","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Spring Data REST is a fantastic tool for rapidly exposing your JPA entities as hypermedia-driven REST APIs. However, even the most intuitive APIs benefit from clear and comprehensive documentation. While HATEOAS provides discoverability at runtime, static documentation offers a bird\u2019s-eye view, making it easier for developers to understand the API\u2019s\u2026","rel":"","context":"In &quot;Spring Rest&quot;","block_context":{"text":"Spring Rest","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_rest\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/network-5987786_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/network-5987786_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/network-5987786_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/network-5987786_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/network-5987786_1280-jpg.avif 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3824","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/comments?post=3824"}],"version-history":[{"count":1,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3824\/revisions"}],"predecessor-version":[{"id":3825,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3824\/revisions\/3825"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/3519"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=3824"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=3824"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=3824"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=3824"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}