{"id":3179,"date":"2026-01-15T10:00:01","date_gmt":"2026-01-15T15:00:01","guid":{"rendered":"https:\/\/www.mymiller.name\/wordpress\/?p=3179"},"modified":"2026-01-15T10:00:01","modified_gmt":"2026-01-15T15:00:01","slug":"understanding-json-data-processing-with-java-exploring-the-jsonfieldprocessor-class","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/java_extra\/understanding-json-data-processing-with-java-exploring-the-jsonfieldprocessor-class\/","title":{"rendered":"Understanding JSON Data Processing with Java: Exploring the JsonFieldProcessor Class"},"content":{"rendered":"\n<ol class=\"wp-block-list\">\n<li><\/li>\n<\/ol>\n\n\n\n<p>In today&#8217;s digital era, data comes in various formats, with JSON (JavaScript Object Notation) being one of the most popular for representing structured data. Manipulating and processing JSON data efficiently is crucial for many software applications, from web development to data analysis. In this article, we&#8217;ll delve into the workings of the <code>JsonFieldProcessor<\/code> class, a Java component designed to simplify JSON data processing tasks.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Introduction to JsonFieldProcessor:<\/h3>\n\n\n\n<p>The <code>JsonFieldProcessor<\/code> class serves as a versatile tool for working with JSON data structures in Java applications. Developed as part of a redesign project, this class provides methods for traversing JSON trees, processing specific fields, and extracting valuable insights from JSON datasets.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Key Features and Functionality:<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Method Overriding for Field Processing:<\/strong>\n<ul class=\"wp-block-list\">\n<li>One of the core features of the <code>JsonFieldProcessor<\/code> class is the <code>processField()<\/code> method, which acts as a template for processing individual fields within a JSON structure. Users can extend this class and override the <code>processField()<\/code> method to implement custom processing logic tailored to their application&#8217;s requirements.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Traversal and Stream Generation:<\/strong>\n<ul class=\"wp-block-list\">\n<li>The class offers methods for traversing JSON trees and generating streams of key-value pairs representing paths and corresponding nodes within the JSON structure. This functionality enables efficient data extraction and manipulation operations on JSON data.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Internal Field Search and Processing:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Internally, the <code>JsonFieldProcessor<\/code> class employs recursive algorithms to search for specific fields within the JSON tree. Once a target field is found, the class invokes the overridden <code>processField()<\/code> method, allowing users to perform custom processing on the identified fields.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Node Retrieval and Path Generation:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Additionally, the class provides utility methods for retrieving parent and current nodes based on a given list of parent nodes. It also facilitates the generation of standardized paths for nodes within the JSON tree, simplifying data referencing and manipulation tasks.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Practical Applications:<\/h3>\n\n\n\n<p>The <code>JsonFieldProcessor<\/code> class can be applied in various scenarios, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Data Extraction: Efficiently extract relevant information from large JSON datasets by specifying target fields for processing.<\/li>\n\n\n\n<li>Data Transformation: Perform data transformation tasks such as filtering, mapping, or aggregating JSON data based on specific criteria.<\/li>\n\n\n\n<li>Data Analysis: Analyze JSON data structures to identify patterns, trends, or anomalies within the dataset.<\/li>\n<\/ul>\n\n\n\n<p>The <code>JsonFieldProcessor<\/code> class provides a powerful toolkit for Java developers to streamline JSON data processing tasks in their applications. By leveraging its features for traversal, field processing, and stream generation, developers can build robust and efficient solutions for working with JSON data. Whether it&#8217;s extracting insights from complex JSON datasets or performing data transformations, the <code>JsonFieldProcessor<\/code> class serves as a valuable asset for modern software development projects.<\/p>\n\n\n\n<p>Here is the code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nextrials.designtool.redesign.changelog.processors;\n\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.node.ArrayNode;\nimport com.fasterxml.jackson.databind.node.ObjectNode;\nimport com.nextrials.designtool.redesign.publish.dto.utils.ListUtils;\nimport lombok.extern.slf4j.Slf4j;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.*;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\nimport java.util.stream.StreamSupport;\n\n\n\/**\n * Basic processor for working with Json Database manipulation\n *\/\n@Slf4j\npublic class JsonFieldProcessor {\n\n    \/**\n     * Method to override for processing indicated fields\n     * @param prefix List of previous nodes in the tree\n     * @param rootNode Root of the tree\n     *\/\n    protected void processField(List&lt;String&gt; prefix, JsonNode rootNode ) {\n        throw new UnsupportedOperationException();\n    }\n\n    \/**\n     * Method to determine if String is an integer\n     * @param strNum String contain text to test.\n     * @return boolean indicating if text is an integer.\n     *\/\n    protected boolean isInteger(String strNum) {\n        if (strNum == null) {\n            return false;\n        }\n        try {\n            Integer.parseInt(strNum);\n        } catch (NumberFormatException nfe) {\n            return false;\n        }\n        return true;\n    }\n\n    \/**\n     * Method to generate a standard display for the tree path\n     * @param prefix List of parent tree nodes\n     * @return String with the standardized path\n     *\/\n    protected String generatePath(List&lt;String&gt; prefix) {\n        return \"\/\" + String.join(\"\/\", ListUtils.safe(prefix));\n    }\n\n    \/**\n     * Must override processField to use this.  Will call process field for all nodes with key\n     * found in findFields.\n     * @param rootNode Root of tree\n     * @param findFields List of field names to search for to call processing on.\n     *\/\n    public void process( JsonNode rootNode, List&lt;String&gt; findFields) {\n        this.findFields(null,rootNode,findFields,rootNode);\n    }\n\n    \/**\n     * Generate a stream that contains key that is path, and value that is the node for that path\n     * @param rootNode Root of tree\n     * @return stream of Map.Entry&lt;String, JsonNode&gt;\n     *\/\n    public Stream&lt;Map.Entry&lt;String, JsonNode&gt;&gt; stream(JsonNode rootNode) {\n        Map&lt;String,JsonNode&gt; map = new HashMap&lt;&gt;();\n        this.stream(null,rootNode,map);\n\n        return map.entrySet().stream();\n    }\n\n    \/**\n     * Method to generate the Map of all nodes with paths\n     * @param prefix List of parent nodes\n     * @param currentNode Node for processing\n     * @param map Map containing the list of paths\/nodes.\n     *\/\n    protected void stream(List&lt;String&gt; prefix, JsonNode currentNode, Map&lt;String,JsonNode&gt; map) {\n        map.put(this.generatePath(prefix),currentNode);\n\n        if (currentNode.isArray()) {\n            ArrayNode arrayNode = (ArrayNode) currentNode;\n            Iterator&lt;JsonNode&gt; node = arrayNode.elements();\n            int index = 0;\n            while (node.hasNext()) {\n                List&lt;String&gt; nextList;\n                if (prefix == null) {\n                    nextList = new ArrayList&lt;&gt;();\n                } else {\n                    nextList = new ArrayList&lt;&gt;(prefix);\n                }\n                nextList.add(String.valueOf(index));\n                this.stream(nextList, node.next(),map);\n                index += 1;\n            }\n        } else if (currentNode.isObject()) {\n            List&lt;Map.Entry&lt;String, JsonNode&gt;&gt; actualList = getFields(currentNode);\n\n            actualList.forEach(entry -&gt; {\n                List&lt;String&gt; nextList;\n                if (prefix == null) {\n                    nextList = new ArrayList&lt;&gt;();\n                } else {\n                    nextList = new ArrayList&lt;&gt;(prefix);\n                }\n                nextList.add(entry.getKey());\n                this.stream(nextList, entry.getValue(),map);\n            });\n        }\n    }\n\n    \/**\n     * Method to convert fields to list\n     * @param currentNode Node to extract fields\n     * @return List of fields\n     *\/\n    @NotNull\n    private List&lt;Map.Entry&lt;String, JsonNode&gt;&gt; getFields(JsonNode currentNode) {\n        Iterator&lt;Map.Entry&lt;String, JsonNode&gt;&gt; fields = currentNode.fields();\n        Iterable&lt;Map.Entry&lt;String, JsonNode&gt;&gt; iterable = () -&gt; fields;\n\n        return StreamSupport\n                .stream(iterable.spliterator(), false)\n                .collect(Collectors.toList());\n    }\n\n    \/**\n     * Method used internally to find fields and recursively search the tree for fields to process.\n     * @param prefix List of parent nodes\n     * @param rootNode Root of tree\n     * @param findFields List of fields to find and call processField on.\n     * @param currentNode Current node\n     *\/\n    protected void findFields(List&lt;String&gt; prefix, JsonNode rootNode, List&lt;String&gt; findFields, JsonNode currentNode) {\n        if (currentNode.isArray()) {\n            ArrayNode arrayNode = (ArrayNode) currentNode;\n            Iterator&lt;JsonNode&gt; node = arrayNode.elements();\n            int index = 0;\n            while (node.hasNext()) {\n                List&lt;String&gt; nextList;\n                if (prefix == null) {\n                    nextList = new ArrayList&lt;&gt;();\n                } else {\n                    nextList = new ArrayList&lt;&gt;(prefix);\n                }\n                nextList.add(String.valueOf(index));\n                this.findFields(nextList, rootNode, findFields, node.next());\n                index += 1;\n            }\n        } else if (currentNode.isObject()) {\n            List&lt;Map.Entry&lt;String, JsonNode&gt;&gt; actualList = getFields(currentNode);\n\n            actualList.forEach(entry -&gt; {\n                List&lt;String&gt; nextList;\n                if (prefix == null) {\n                    nextList = new ArrayList&lt;&gt;();\n                } else {\n                    nextList = new ArrayList&lt;&gt;(prefix);\n                }\n                nextList.add(entry.getKey());\n                this.findFields(nextList, rootNode, findFields, entry.getValue());\n            });\n        } else {\n            if (findFields.contains(prefix.get(prefix.size() - 1))) {\n                if(log.isDebugEnabled()) {\n                    log.debug(\"Processing: {} with value: {}\",this.generatePath(prefix),  currentNode);\n                }\n                this.processField(prefix, rootNode);\n            }\n        }\n    }\n\n    \/**\n     * Return the parent node with the given parent list\n     * @param prefix List of parent nodes\n     * @param rootNode Root of Tree\n     * @return ObjectNode that is the parent\n     *\/\n    protected ObjectNode findParentNode(List&lt;String&gt; prefix, JsonNode rootNode ) {\n        JsonNode locatedNode = rootNode;\n        if(prefix != null) {\n            for(int i = 0; i &lt; prefix.size() -1 ; i++) {\n                String value = prefix.get(i);\n                if(isInteger(value)) {\n                    locatedNode = locatedNode.path(Integer.parseInt(value));\n                } else {\n                    locatedNode = locatedNode.path(value);\n                }\n            }\n        }\n        return (ObjectNode) locatedNode;\n    }\n\n    \/**\n     * Return the current node give the prefix list\n     * @param prefix List of parent nodes\n     * @param rootNode Root of Tree\n     * @return JsonNode indicating the current node\n     *\/\n    protected JsonNode findCurrentNode(List&lt;String&gt; prefix, JsonNode rootNode ) {\n        JsonNode locatedNode = rootNode;\n        if (prefix != null) {\n            for (String value : prefix) {\n                if (isInteger(value)) {\n                    locatedNode = locatedNode.path(Integer.parseInt(value));\n                } else {\n                    locatedNode = locatedNode.path(value);\n                }\n            }\n        }\n        return locatedNode;\n    }\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In today&#8217;s digital era, data comes in various formats, with JSON (JavaScript Object Notation) being one of the most popular for representing structured data. Manipulating and processing JSON data efficiently is crucial for many software applications, from web development to data analysis. In this article, we&#8217;ll delve into the workings of the JsonFieldProcessor class, a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3497,"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":[457],"tags":[],"series":[],"class_list":["post-3179","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java_extra"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/data-7798787_640.png?fit=640%2C640&ssl=1","jetpack-related-posts":[{"id":3421,"url":"https:\/\/www.mymiller.name\/wordpress\/java_extra\/convert-csv-to-json-and-json-to-csv-with-csvjsonconverter\/","url_meta":{"origin":3179,"position":0},"title":"Convert CSV to JSON and JSON to CSV with CSVJSONConverter","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"In today's data-driven world, it's common to work with different data formats like CSV (Comma-Separated Values) and JSON (JavaScript Object Notation). Converting data between these formats is a common task in data processing and integration workflows. In this article, we'll explore how to use the CSVJSONConverter class, a versatile utility\u2026","rel":"","context":"In &quot;Java Extras&quot;","block_context":{"text":"Java Extras","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java_extra\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/07\/computer-g610baba23_640.jpg?fit=640%2C360&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/07\/computer-g610baba23_640.jpg?fit=640%2C360&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/07\/computer-g610baba23_640.jpg?fit=640%2C360&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":2449,"url":"https:\/\/www.mymiller.name\/wordpress\/java\/jackson-configuration\/","url_meta":{"origin":3179,"position":1},"title":"Jackson Configuration","author":"Jeffery Miller","date":"December 23, 2025","format":false,"excerpt":"Jackson configuration for JSON to POJO conversion. Standard conversion for converting JSON to POJO objects for Rest APIs and other implementations.","rel":"","context":"In &quot;JAVA&quot;","block_context":{"text":"JAVA","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java\/"},"img":{"alt_text":"Jackson configuration","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2019\/05\/analytics-3088958_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2019\/05\/analytics-3088958_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2019\/05\/analytics-3088958_640.jpg?fit=640%2C426&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3704,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_databases\/mastering-location-data-with-spring-jpa-a-comprehensive-guide\/","url_meta":{"origin":3179,"position":2},"title":"Mastering Location Data with Spring JPA: A Comprehensive Guide","author":"Jeffery Miller","date":"November 24, 2025","format":false,"excerpt":"In today\u2019s interconnected world, location data plays a pivotal role in numerous applications, from e-commerce and logistics to travel and social networking. Efficiently managing and accessing this wealth of geographical information is crucial for developers. This article delves into the realm of location data management using Spring JPA (Java Persistence\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\/09\/international-1751293_1280.png?fit=1186%2C1200&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/international-1751293_1280.png?fit=1186%2C1200&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/international-1751293_1280.png?fit=1186%2C1200&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/international-1751293_1280.png?fit=1186%2C1200&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/international-1751293_1280.png?fit=1186%2C1200&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3890,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_messaging\/spring-cloud-stream\/","url_meta":{"origin":3179,"position":3},"title":"Spring Cloud Stream","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Spring Cloud Stream is a framework for building highly scalable, event-driven microservices that are connected by a shared messaging system. In simple terms, it's a powerful tool that takes away the complexity of communicating with message brokers like RabbitMQ or Apache Kafka, allowing you to focus purely on your application's\u2026","rel":"","context":"In &quot;Spring Messaging&quot;","block_context":{"text":"Spring Messaging","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_messaging\/"},"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":3568,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_rest\/spring-data-rest-simplify-restful-api-development-2\/","url_meta":{"origin":3179,"position":4},"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":3844,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_messaging\/the-power-of-kafka-connect\/","url_meta":{"origin":3179,"position":5},"title":"The Power of Kafka Connect","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Kafka Connect is a powerful framework for streaming data between Kafka and other systems in a scalable and reliable way. Connectors handle the complexities of data integration, allowing you to focus on your core application logic. Sink Connectors are used to export data from Kafka to other systems, and in\u2026","rel":"","context":"In &quot;Spring Messaging&quot;","block_context":{"text":"Spring Messaging","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_messaging\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/ai-generated-8131434_1280-png.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/ai-generated-8131434_1280-png.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/ai-generated-8131434_1280-png.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/ai-generated-8131434_1280-png.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/ai-generated-8131434_1280-png.avif 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3179","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=3179"}],"version-history":[{"count":2,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3179\/revisions"}],"predecessor-version":[{"id":3498,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3179\/revisions\/3498"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/3497"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=3179"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=3179"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=3179"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=3179"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}