{"id":3935,"date":"2025-11-25T10:00:00","date_gmt":"2025-11-25T15:00:00","guid":{"rendered":"https:\/\/www.mymiller.name\/wordpress\/?p=3935"},"modified":"2025-11-16T22:56:16","modified_gmt":"2025-11-17T03:56:16","slug":"%f0%9f%9a%80-dl4j-and-spring-boot-real-time-anomaly-detection-in-time-series-data","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/spring_ai\/%f0%9f%9a%80-dl4j-and-spring-boot-real-time-anomaly-detection-in-time-series-data\/","title":{"rendered":"\ud83d\ude80 DL4J and Spring Boot: Real-Time Anomaly Detection in Time-Series Data"},"content":{"rendered":"\n<p>As a Software Architect, you understand that an excellent solution requires not just a powerful model, but a <strong>robust, scalable, and performant architecture<\/strong> for deployment. The combination of <strong>DL4J<\/strong> (Deeplearning4j) and <strong>Spring Boot<\/strong> is perfectly suited for building real-time, high-performance services, especially for a critical task like time-series anomaly detection.<\/p>\n\n\n\n<p>This article outlines a practical, architecturally sound approach to deploying a trained DL4J deep learning model (like an <strong>LSTM Autoencoder<\/strong>) within a Spring Boot application to handle streaming data.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">1. The Architectural Blueprint: Performance and Scalability<\/h3>\n\n\n\n<p>The goal is to minimize inference latency on streaming data. A RESTful microservice built with Spring Boot offers the perfect low-latency gateway.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><td><strong>Component<\/strong><\/td><td><strong>Technology<\/strong><\/td><td><strong>Role<\/strong><\/td><td><strong>Architectural Benefit<\/strong><\/td><\/tr><\/thead><tbody><tr><td><strong>Model<\/strong><\/td><td>DL4J (e.g., LSTM Autoencoder)<\/td><td>The core anomaly detection logic.<\/td><td>Native JVM performance, avoiding inter-process communication overhead.<\/td><\/tr><tr><td><strong>Application<\/strong><\/td><td>Spring Boot (Java)<\/td><td>The service container and REST API endpoint.<\/td><td>Rapid development, built-in dependency injection, and easy deployment as an executable JAR.<\/td><\/tr><tr><td><strong>Data Storage<\/strong><\/td><td>Time-Series Database (e.g., Prometheus, InfluxDB) or a Streaming Platform (e.g., Kafka)<\/td><td>Source of streaming data.<\/td><td>Decoupling of the detection service from the data source for better scalability.<\/td><\/tr><tr><td><strong>Numerical Backend<\/strong><\/td><td>ND4J (N-Dimensional Array for Java)<\/td><td>Handles the complex matrix math for the DL4J model.<\/td><td>Optimized, high-performance numerical computing for inference.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">2. Setting Up the Spring Boot Project (with Gradle)<\/h3>\n\n\n\n<p>Since you prefer <strong>Gradle<\/strong> and <strong>Spring Boot<\/strong>, the first step is configuring your <code>build.gradle<\/code> file to include the necessary DL4J and ND4J dependencies, alongside the Spring Boot Web starter.<\/p>\n\n\n\n<p>Groovy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dependencies {\n    \/\/ Spring Boot\n    implementation 'org.springframework.boot:spring-boot-starter-web'\n\n    \/\/ DL4J and ND4J Dependencies (use the latest stable release)\n    def dl4jVersion = '1.0.0-M2' \n    implementation \"org.deeplearning4j:deeplearning4j-core:${dl4jVersion}\"\n    implementation \"org.nd4j:nd4j-native-platform:${dl4jVersion}\" \n    \/\/ Add other backends if needed (e.g., GPU\/CUDA)\n    \n    \/\/ Lombok (optional, but helpful)\n    compileOnly 'org.projectlombok:lombok'\n    annotationProcessor 'org.projectlombok:lombok'\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3. Loading the DL4J Model: The Service Layer<\/h3>\n\n\n\n<p>The key to high-performance real-time prediction is to <strong>load the trained model once<\/strong> at application startup and reuse the loaded object for all incoming requests.<\/p>\n\n\n\n<p>You should use a <strong>Spring <code>@Component<\/code><\/strong> or <strong><code>@Service<\/code><\/strong> with a <code>@PostConstruct<\/code> annotation for this initial loading, ensuring the model is ready before the service can accept traffic. DL4J uses the <code>ModelSerializer<\/code> class for this purpose.<\/p>\n\n\n\n<p>Java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;\nimport org.deeplearning4j.util.ModelSerializer;\nimport org.springframework.stereotype.Service;\n\n@Service\npublic class AnomalyDetectionService {\n\n    private MultiLayerNetwork anomalyModel;\n    \n    \/\/ Path to your saved DL4J model file (e.g., in src\/main\/resources)\n    private final String MODEL_PATH = \"lstm_autoencoder_ts.zip\";\n\n    @PostConstruct\n    public void init() {\n        try {\n            \/\/ Load the model from the resources folder\n            File modelFile = new ClassPathResource(MODEL_PATH).getFile();\n            anomalyModel = ModelSerializer.restoreMultiLayerNetwork(modelFile);\n            log.info(\"DL4J Time-Series Model Loaded Successfully!\");\n        } catch (IOException e) {\n            log.error(\"Failed to load DL4J model!\", e);\n            throw new RuntimeException(\"Model initialization failed.\", e);\n        }\n    }\n    \n    public double detect(INDArray timeSeriesWindow) {\n        \/\/ ... (Prediction logic described below)\n    }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4. Implementing Real-Time Inference (The Prediction Endpoint)<\/h3>\n\n\n\n<p>The Spring Boot <strong><code>@RestController<\/code><\/strong> will expose an endpoint\u2014for instance, a <strong><code>POST<\/code><\/strong> endpoint that accepts a window of time-series data.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Architectural Note:<\/strong> Per the user&#8217;s explicit preference, note that the <strong><code>POST<\/code><\/strong> method is used here for the request body, as only <code>PUT<\/code> and <code>PUSH<\/code> methods (and in practice, <code>POST<\/code> and <code>PATCH<\/code>) typically allow a Request <em>Body<\/em> payload in Spring to send the time-series window data.<\/p>\n<\/blockquote>\n\n\n\n<p>The core logic within the controller involves:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Preprocessing:<\/strong> Converting the incoming JSON\/data structure into the DL4J&#8217;s native numerical format, an <strong><code>INDArray<\/code><\/strong> (ND4J object). This is a critical step, as the data must match the shape and normalization used during model training.<\/li>\n\n\n\n<li><strong>Inference:<\/strong> Calling the loaded <code>anomalyModel.output()<\/code> method.<\/li>\n\n\n\n<li><strong>Post-processing\/Anomaly Check:<\/strong> For an LSTM Autoencoder, the model predicts the reconstruction of the input. A high reconstruction error (the difference between input and output) indicates an <strong>anomaly<\/strong>.<\/li>\n<\/ol>\n\n\n\n<p>Java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import org.nd4j.linalg.api.ndarray.INDArray;\nimport org.nd4j.linalg.factory.Nd4j;\nimport org.springframework.web.bind.annotation.*;\n\n@RestController\n@RequestMapping(\"\/api\/ts\/anomaly\")\npublic class AnomalyController {\n\n    @Autowired\n    private AnomalyDetectionService service;\n\n    \/**\n     * Accepts a window of time-series data for anomaly detection.\n     * The input is an array of feature vectors (time steps).\n     *\/\n    @PostMapping\n    public AnomalyResponse detectAnomaly(@RequestBody TimeSeriesWindow window) {\n        \/\/ 1. Convert input data (window) to INDArray for DL4J\n        INDArray inputMatrix = Nd4j.create(window.getFlattenedData(), new int&#91;]{1, window.getTimeSteps(), window.getFeatures()});\n\n        \/\/ 2. Perform Inference\n        INDArray outputMatrix = service.getAnomalyModel().output(inputMatrix);\n        \n        \/\/ 3. Calculate Anomaly Score (Reconstruction Error)\n        double anomalyScore = calculateReconstructionError(inputMatrix, outputMatrix);\n        \n        boolean isAnomaly = anomalyScore &gt; ANOMALY_THRESHOLD; \/\/ Define a threshold\n\n        return new AnomalyResponse(isAnomaly, anomalyScore);\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>By tightly integrating <strong>DL4J<\/strong> with a <strong>Spring Boot REST API<\/strong>, you create a highly efficient, real-time inferencing engine. This architecture provides the performance needed to handle continuous streams of time-series data while leveraging the robust, production-ready nature of the Spring framework.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>As a Software Architect, you understand that an excellent solution requires not just a powerful model, but a robust, scalable, and performant architecture for deployment. The combination of DL4J (Deeplearning4j) and Spring Boot is perfectly suited for building real-time, high-performance services, especially for a critical task like time-series anomaly detection. This article outlines a practical, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3936,"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":[443],"tags":[429,482,319],"series":[],"class_list":["post-3935","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-spring_ai","tag-ai","tag-dl4j","tag-spring"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/11\/Gemini_Generated_Image_ek9cohek9cohek9c.avif","jetpack-related-posts":[{"id":3564,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_ai\/anomaly-detection-in-spring-boot-gateway-with-ai-and-dl4j-unsupervised-learning-approach\/","url_meta":{"origin":3935,"position":0},"title":"Anomaly Detection in Spring Boot Gateway with AI and DL4J: Unsupervised Learning Approach","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"In this article, we\u2019ll focus on using unsupervised learning with DL4J to detect anomalies in data traffic passing through your Spring Boot Gateway. This is especially useful when you don\u2019t have labeled data on what constitutes \u201cnormal\u201d vs. \u201canomalous\u201d traffic. Potential Features for Anomaly Detection in API Gateway Traffic The\u2026","rel":"","context":"In &quot;Spring AI&quot;","block_context":{"text":"Spring AI","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_ai\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_rzr70rzr70rzr70r.jpg?fit=1200%2C1200&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_rzr70rzr70rzr70r.jpg?fit=1200%2C1200&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_rzr70rzr70rzr70r.jpg?fit=1200%2C1200&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_rzr70rzr70rzr70r.jpg?fit=1200%2C1200&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_rzr70rzr70rzr70r.jpg?fit=1200%2C1200&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3574,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_ai\/deeplearning4j-and-spring-boot-a-powerful-duo-for-ai-powered-applications\/","url_meta":{"origin":3935,"position":1},"title":"Deeplearning4J and Spring Boot: A Powerful Duo for AI-Powered Applications","author":"Jeffery Miller","date":"September 22, 2025","format":false,"excerpt":"Deeplearning4J (DL4J) offers a comprehensive Java framework for deep learning, while Spring Boot streamlines the development of production-ready applications. By combining these two technologies, you unlock a flexible platform for building intelligent services that can handle various types of data. In this guide, we\u2019ll explore how to integrate DL4J into\u2026","rel":"","context":"In &quot;Spring AI&quot;","block_context":{"text":"Spring AI","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_ai\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8453379_1280.jpg?fit=800%2C1200&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-8453379_1280.jpg?fit=800%2C1200&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8453379_1280.jpg?fit=800%2C1200&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8453379_1280.jpg?fit=800%2C1200&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":3951,"url":"https:\/\/www.mymiller.name\/wordpress\/java\/scaling-streams-mastering-virtual-threads-in-spring-boot-4-and-java-25\/","url_meta":{"origin":3935,"position":2},"title":"Scaling Streams: Mastering Virtual Threads in Spring Boot 4 and Java 25","author":"Jeffery Miller","date":"December 22, 2025","format":false,"excerpt":"As a software architect, I\u2019ve seen the industry shift from heavy platform threads to reactive streams, and finally to the \"best of both worlds\": Virtual Threads. With the recent release of Spring Boot 4.0 and Java 25 (LTS), Project Loom's innovations have officially become the bedrock of high-concurrency enterprise Java.\u2026","rel":"","context":"In &quot;JAVA&quot;","block_context":{"text":"JAVA","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/12\/Gemini_Generated_Image_wqijejwqijejwqij-scaled.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/12\/Gemini_Generated_Image_wqijejwqijejwqij-scaled.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/12\/Gemini_Generated_Image_wqijejwqijejwqij-scaled.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/12\/Gemini_Generated_Image_wqijejwqijejwqij-scaled.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/12\/Gemini_Generated_Image_wqijejwqijejwqij-scaled.avif 3x"},"classes":[]},{"id":3582,"url":"https:\/\/www.mymiller.name\/wordpress\/spring\/leveraging-dicom-in-spring-boot-applications\/","url_meta":{"origin":3935,"position":3},"title":"Leveraging DICOM in Spring Boot Applications","author":"Jeffery Miller","date":"November 19, 2025","format":false,"excerpt":"Leveraging DICOM in Spring Boot Applications DICOM, the cornerstone of medical imaging, is a specialized format for storing and transmitting medical images and related information. Integrating it into your Spring Boot project opens up a world of possibilities for medical applications. Let\u2019s explore how to achieve this. Understanding DICOM DICOM\u2026","rel":"","context":"In &quot;Spring&quot;","block_context":{"text":"Spring","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/x-ray-6841384_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\/x-ray-6841384_1280.jpg?fit=1200%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/x-ray-6841384_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\/x-ray-6841384_1280.jpg?fit=1200%2C800&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/x-ray-6841384_1280.jpg?fit=1200%2C800&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3560,"url":"https:\/\/www.mymiller.name\/wordpress\/spng_security\/zero-trust-with-spring-boot-deep-dive-into-security\/","url_meta":{"origin":3935,"position":4},"title":"Zero Trust with Spring Boot: Deep Dive into Security","author":"Jeffery Miller","date":"September 22, 2025","format":false,"excerpt":"Zero Trust is a paradigm shift in security, assuming no inherent trust within a network. Implementing Zero Trust principles with Spring Boot fortifies your microservices against modern threats. Let\u2019s delve deeper into the key concepts: Secure Communication (HTTPS\/TLS): Encryption: HTTPS encrypts all communication between microservices, preventing eavesdropping and data tampering.\u2026","rel":"","context":"In &quot;Spring Security&quot;","block_context":{"text":"Spring Security","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spng_security\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_y76fbby76fbby76f.jpg?fit=1200%2C1200&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_y76fbby76fbby76f.jpg?fit=1200%2C1200&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_y76fbby76fbby76f.jpg?fit=1200%2C1200&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_y76fbby76fbby76f.jpg?fit=1200%2C1200&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_y76fbby76fbby76f.jpg?fit=1200%2C1200&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3912,"url":"https:\/\/www.mymiller.name\/wordpress\/uncategorized\/spring-boot-4-0-whats-next-for-the-modern-java-architect\/","url_meta":{"origin":3935,"position":5},"title":"Spring Boot 4.0: What&#8217;s Next for the Modern Java Architect?","author":"Jeffery Miller","date":"September 24, 2025","format":false,"excerpt":"A Forward-Looking Comparison of Spring Boot 3.x and 4.0 Staying on top of the rapidly evolving Java ecosystem is paramount for any software architect. The shift from Spring Boot 2.x to 3.x brought significant changes, notably the move to Jakarta EE. Now, with the horizon of Spring Boot 4.0 and\u2026","rel":"","context":"Similar post","block_context":{"text":"Similar post","link":""},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/09\/per-2056740_1280.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/09\/per-2056740_1280.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/09\/per-2056740_1280.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/09\/per-2056740_1280.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/09\/per-2056740_1280.avif 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3935","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=3935"}],"version-history":[{"count":1,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3935\/revisions"}],"predecessor-version":[{"id":3937,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3935\/revisions\/3937"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/3936"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=3935"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=3935"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=3935"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=3935"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}