{"id":1165,"date":"2016-08-02T19:39:20","date_gmt":"2016-08-02T17:39:20","guid":{"rendered":"http:\/\/invidit.de\/blog\/?p=1165"},"modified":"2020-09-21T11:53:24","modified_gmt":"2020-09-21T09:53:24","slug":"wie-funktioniert-eigentlich-diese-api","status":"publish","type":"post","link":"https:\/\/invidit.de\/blog\/wie-funktioniert-eigentlich-diese-api\/","title":{"rendered":"Wie funktioniert eigentlich diese API?"},"content":{"rendered":"<p>Hallo Spa\u00df-Coder.<\/p>\n<p>Das agile Manifesto<sup>[1]\u00a0 <\/sup>besagt unter anderem <span style=\"font-size: 10pt;\">&#8222;<\/span><span style=\"font-size: 12pt;\">Funktionierende Software mehr als umfassende Dokumentation<\/span>&#8222;. Damit ist jedoch nicht gemeint, dass ein Softwareprojekt keine Dokumentation enthalten sollte. Wer hat selbst schon einmal versucht eine API zu verwenden und sich dann m\u00fchsam durch Versuch und Irrtum sehr z\u00e4h dem gew\u00fcnschten Ergebnis gen\u00e4hert? Oder eine f\u00fcnf Jahre alte Dokumentation zu Hilfe genommen, weil es keine aktuelle Ausf\u00fchrung gibt? Anders als bei Wein wird eine Doku durch lange Lagerung ohne Einfluss von Au\u00dfen nicht besser mit der Zeit.<\/p>\n<p>In diesem Artikel schauen wir uns verschiedene Dokumentationswerkzeuge an. Das Ziel ist jeweils, die API zu dokumentieren und nicht das gesamte Projekt (wie etwa mit Javadoc<sup>[2]<\/sup>). Wir stellen vier verschiedene Werkzeuge f\u00fcr die Dokumentation einer REST-API in Java vor und zeigen am Ende des Artikels einen Vergleich der Werkzeuge auf.<\/p>\n<h1>Spring REST Doc<sup>[3]<\/sup><\/h1>\n<p>Wie der Name bereits vermuten l\u00e4sst, handelt es sich bei <em>Spring REST Doc<\/em> um eine Erweiterung von Spring. Die Idee dabei ist, mit Hilfe der <strong>API-Tests<\/strong> Dokumentationsschnipsel zu generieren, welche per AsciiDoctor oder Markdown zu einer Doku konsolidiert und gerendert werden. Die Tests werden hierbei mit Spring MVC Test (via. MockMvc) oder REST Assured geschrieben.<\/p>\n<p>Ein Test sieht mit Spring MVC Test dann so aus<strong>:<\/strong><\/p>\n<pre class=\"\">@Test\npublic void getPerson() throws Exception {\n    this.mockMvc.perform(get(\"\/persons\/{id}\", this.personOne.getId()))\n            .andExpect(status().isOk())\n            .andExpect(content().contentType(MediaTypes.HAL_JSON))\n            .andExpect(jsonPath(\"$.person.name\", is(this.personOne.getName())))\n            .andExpect(jsonPath(\"$.person.firstname\", is(this.personOne.getFirstname())))\n            .andDo(this.document.snippets(\n                    pathParameters(\n                            parameterWithName(\"id\").description(\"The id to find the person with.\")\n                    ),\n                    responseFields(\n                            fieldWithPath(\"person.id\").description(\"The person's id\"),\n                            fieldWithPath(\"person.name\").description(\"The person's name\"),\n                            fieldWithPath(\"person.firstname\").description(\"The person's first name\"),\n                            fieldWithPath(\"_links\").description(\"Links to this resource\")\n                    ),\n                    links(halLinks(),\n                            linkWithRel(\"self\").description(\"Link to this resource.\")\n                    )\n            ));\n}<\/pre>\n<p>Bei Ausf\u00fchrung der Test werden nach der Konfiguration von Maven oder Gradle verschiedene Textschnipsel erzeugt, z.B. f\u00fcr die durchgef\u00fchrte Anfrage und die Antwort. Diese Schnipsel werden \u00fcber AsciiDoc (adoc) Dateien dann zu einer Dokumentation zusammengefasst, welche z.B. als HTML gerendert wird.<\/p>\n<p>Weitere Beispiele sind zu finden unter: https:\/\/github.com\/spring-projects\/spring-restdocs\/tree\/master\/samples<\/p>\n<h1>JSONDoc<sup>[4]<\/sup><\/h1>\n<p>JSONDoc verfolgt einen sehr geradlinigen Ansatz bei der Erstellung der Dokumentation. So werden die notwendigen Annotationen f\u00fcr die Dokumentation direkt an die Controller-Methoden und den DTO-Objekten geschrieben. Was auf den ersten Blick als \u00dcberfrachtung des Live-Codes aussieht wirkt nach kurzer Eingew\u00f6hnung wie aus einem Guss. Die Dokumentation passt zum Code und h\u00e4lt alle Details zur API an einem Ort vorr\u00e4tig.<\/p>\n<p>Durch Erweiterungsmodule f\u00fcr Spring MVC und Spring Boot wird ein gro\u00dfer Teil der Dokumentation bereits aus den Spring-Annotationen generiert. So m\u00fcssen nur noch weiterf\u00fchrende Informationen in den speziellen JSONDoc Annotationen geschrieben werden.<\/p>\n<p>Eine, mithilfe von JSONDoc beschriebene, Spring MVC basierte Controller-Methode kann etwa folgenderma\u00dfen aussehen:<\/p>\n<pre class=\"lang:default decode:true\">@Api(name = \"Person Service\",\n\t\tdescription = \"This service provides methods to fetch information about Persons.\",\n\t\tgroup = \"Master Data\",\n\t\tvisibility = ApiVisibility.PUBLIC,\n\t\tstage = ApiStage.GA)\n@ApiVersion(since = \"V1\")\n@ApiAuthToken\n@RestController\n@RequestMapping(\"api\/v1\/persons\")\npublic class PersonApiController {\n\n\tprivate final PersonRepository personRepository;\n\tprivate final PersonApiAssembler personApiAssembler;\n\n\t@Inject\n\tpublic PersonApiController(PersonRepository personRepository, \n                                   PersonApiAssembler personApiAssembler) {\n\t\tthis.personRepository = personRepository;\n\t\tthis.personApiAssembler = personApiAssembler;\n\t}\n\n    @ApiMethod(description = \"Returns the Person with the given id.\")\n    @RequestMapping(value = \"\/{id}\", \n                    method = RequestMethod.GET, \n                    produces = MediaType.APPLICATION_JSON_VALUE)\n    public PersonApiDto getPersonAsJson(@ApiPathParam(name = \"id\", \n                                                      description = \"Id of the person to look up.\")\n                                        @PathVariable UUID id) {\n        Person person = personRepository.findById(id);\n        if(person == null){\n            throw new ResourceNotFoundException();\n        }\n        return personApiAssembler.toDto(person);\n    }\n}<\/pre>\n<p>\u00dcber eine konfigurierte Seite ist von der Applikation nun eine entsprechende Dokumentation als JSON abrufbar. Das JSONDoc-Projekt bietet jsondoc-ui daf\u00fcr eine einfache und komfortable M\u00f6glichkeit, diese interaktiv im Browser einzusehen. Dazu wird das JSON eingelesen und mit Hilfe von Javascript interpretiert. Die resultierende Seite \u00fcber das separate jsondoc-ui sieht in etwa folgenderma\u00dfen aus:<\/p>\n<p><a href=\"http:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/07\/JSONDoc-Service.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-1183\" src=\"http:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/07\/JSONDoc-Service.jpg\" alt=\"JSONDoc-Service\" width=\"832\" height=\"707\" srcset=\"https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/07\/JSONDoc-Service.jpg 832w, https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/07\/JSONDoc-Service-300x255.jpg 300w, https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/07\/JSONDoc-Service-768x653.jpg 768w\" sizes=\"(max-width: 832px) 100vw, 832px\" \/><\/a><\/p>\n<p>Die \u00fcbertragenen Daten werden typischerweise in DTOs verpackt, JSONDoc nennt diese <em>Objekte<\/em> (<em>Objects<\/em>). Ein DTO welches mit Hilfe von JSONDoc beschrieben ist, hat im Code folgenden Aufbau:<\/p>\n<pre class=\"lang:default decode:true\">@ApiObject(name = \"Person\",\n\t\tdescription = \"A Person which stands in any relation to the company and\/or any \" +\n\t\t\t\t\"organisational units managed by the application.\",\n\t\tgroup = \"Master Data\",\n\t\tvisibility = ApiVisibility.PUBLIC,\n\t\tstage = ApiStage.GA)\npublic class PersonApiDto {\n\t@ApiObjectField(description = \"Unique id of the Person\")\n    public UUID id;\n\t@ApiObjectField(description = \"Shows the date of birth of the Person.\",\n\t\t\t\t\tformat = \"YYYY-MM-DD\")\n    public LocalDateTime dateOfBirth;\n\t@ApiObjectField(description = \"First name\")\n\tpublic String firstName;\n\t@ApiObjectField(description = \"Last name\")\n\tpublic String lastName;\n\t@ApiObjectField(description = \"User name of the Person\")\n\tpublic String userName;\n\t@ApiObjectField(description = \"Gender of the Person. Allowed values: \" + \n                                      \"&lt;b&gt;M&lt;\/b&gt;ale, &lt;b&gt;F&lt;\/b&gt;emale, &lt;b&gt;N&lt;\/b&gt;eutral\",\n\t\t\t\t\tallowedvalues = {\"M\", \"F\", \"N\"})\n\tpublic String gender;\n\t@ApiObjectField(description = \"Business contact information of the Person\")\n\tpublic BusinessContactApiDto businessContact;\n\t@ApiObjectField(description = \"Flag whether the Person is active or not.\")\n\tpublic boolean active;\n}\n<\/pre>\n<p>Aussehen wird das Ganze in der jsondoc-ui hinterher wie im folgenden Bild angegeben. Dabei werden die unterschiedlichen Objekte allesamt angezeigt. \u00dcber den Type eines Werts wird deutlich, welches Objekt sich dahinter verbirgt. Die entsprechende Dokumentation kann dann ebenfalls interaktiv aufgerufen werden.<\/p>\n<p><a href=\"http:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/07\/JSONDoc-Object.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-1182\" src=\"http:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/07\/JSONDoc-Object.jpg\" alt=\"JSONDoc-Object\" width=\"1270\" height=\"977\" srcset=\"https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/07\/JSONDoc-Object.jpg 1270w, https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/07\/JSONDoc-Object-300x231.jpg 300w, https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/07\/JSONDoc-Object-768x591.jpg 768w, https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/07\/JSONDoc-Object-1024x788.jpg 1024w\" sizes=\"(max-width: 1270px) 100vw, 1270px\" \/><\/a><\/p>\n<p>Ein eigenes Maven-Modul (jsondoc-maven-plugin) hilft bei der Generierung einer Offline-Dokumentatio. Dies ist notwendig, wenn dem Entwickler, der die API verwenden m\u00f6chte, die Anwendung selbst nicht zur Verf\u00fcgung steht und der Interaktive Abruf damit nicht m\u00f6glich ist. Bei der Offline-Version wird das Ergebnis des JSON-Exports von JSONDoc in die HTML-Seite von jsondoc-ui reingeneriert.<\/p>\n<h1>Swagger<sup>[5]<\/sup><\/h1>\n<p>Swagger kann grunds\u00e4tzlich in allen\u00a0 Java-Projekten genutzt werden. Dennoch schauen wir uns in diesem Artikel nur die spezifische Implementierung f\u00fcr Spring-Projekte an. Die Verwendung in Nicht-Spring-Projekten ist sehr \u00e4hnlich.<\/p>\n<h1>SpringFox<sup>[6]<\/sup><\/h1>\n<p>Spring Fox (ehemals swagger-springmvc) bietet die Integration von Swagger f\u00fcr Spring und Spring Boot Projekte. Mit springfox-staticdocs kann zus\u00e4tzlich eine statische Dokumentation wie bei Spring REST Doc generiert werden, womit hier zwei Ans\u00e4tze kombiniert werden k\u00f6nnen. Zus\u00e4tzlich verringert Spring Fox die Notwendigkeit von Swagger-Annotationen zur Dokumentation im Produktionscode, da die vorhandenen Spring-Annotationen ausgewertet werden. Zus\u00e4tzlich k\u00f6nnen Swagger-Annotationen genutzt werden, um Abweichungen und zus\u00e4tzlich Informationen zu dokumentieren, was in den Entit\u00e4ten sowie im Controller angebracht ist.<\/p>\n<p>SpringFox bringt auch gleich ein entsprechendes UI mit, so dass sich jeder Service selbst dokumentieren kann und die Dokumentation einheitlich auf immer demselben Endpunkt zu finden ist.<\/p>\n<p>Auf Grund der sehr umfangreichen und ausf\u00fchrlichen Dokumentation verzichten wir an dieser Stelle auf zus\u00e4tzliche Beispiele.<\/p>\n<h1>Vergleich der Tools<\/h1>\n<p>Nach der Vorstellung der grunds\u00e4tzliche Funktionsweise stellen wir hier einen Vergleich der Werkzeuge an.<\/p>\n<table class=\"alignleft\" style=\"width: 100%;\" border=\"0\" cellpadding=\"5px\">\n<tbody>\n<tr>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\"><strong>Werkzeug<\/strong><\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\"><strong>Wo schreibe ich die Doku?<\/strong><\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\"><strong>Welche Ausgaben werden erzeugt?<\/strong><\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\"><strong>F\u00fcr welchen Einsatzzweck eignet sich der Ansatz?<\/strong><\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\"><strong>Besonderheiten<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\"><strong>Spring REST Doc<\/strong><\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">Die Beschreibung erfolgt \u00fcber die API-Test. Damit bleibt der Produktionscode unber\u00fchrt. Zus\u00e4tzlich werden manuell adoc-Dateien geschrieben.<\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">&#8211; HTML5<br \/>\n&#8211; DocBook<br \/>\n&#8211; man<\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">&#8211; statische Dokumentation<br \/>\n&#8211; mehr als nur API<\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">Tests schlagen fehl, wenn Dokumentation unvollst\u00e4ndig ist<\/p>\n<p>kombiniert manuell geschriebene Doku und generierte Doku<\/p>\n<p>f\u00fcr Spring \/ Spring Boot Projekte<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\"><strong>JSONDoc<\/strong><\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">Die Beschreibung erfolgt \u00fcber Annotationen in den Controllern des Produktionscodes.<\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">&#8211; JSON<\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">&#8211; interaktive Dokumentation<br \/>\n&#8211; beschreibt nur API<br \/>\n&#8211; offline Dokumentation<\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">Entwickler k\u00f6nnen vor der Nutzung der API diese interaktiv ausprobieren und damit Anfragen und Antworten pr\u00fcfen (in separatem Ausgabemodul)<\/p>\n<p>offline Dokumentation m\u00f6glich (via Maven)<\/p>\n<p>Doku als HTML-Seiten mit Bootstrap-Theme<\/p>\n<p>Erweiterung f\u00fcr Spring \/ Spring Boot Projekte m\u00f6glich<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\"><strong>Swagger<\/strong><\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">Die Beschreibung erfolgt \u00fcber Annotationen in den Controllern des Produktionscodes.<\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">&#8211; JSON<br \/>\n&#8211; YAML<\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">&#8211; interaktive Dokumentation<br \/>\n&#8211; beschreibt nur API<\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">Entwickler k\u00f6nnen vor der Nutzung der API diese interaktiv ausprobieren und damit Anfragen und Antworten pr\u00fcfen<\/p>\n<p>vollst\u00e4ndig generierte Doku<\/p>\n<p>f\u00fcr Java Projekte<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\"><strong>SpringFox<\/strong><\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">\u00dcberwiegend wird die Dokumentation aus den bereits vorhandenen Spring-Annotationen generiert. Swagger Annotation sind zus\u00e4tzlich m\u00f6glich.<\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">&#8211; JSON (swagger)<br \/>\n&#8211; YAML (swagger)<br \/>\n&#8211; adoc (AsciiDoctor)<\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">&#8211; statische und interaktive Dokumentation<\/td>\n<td style=\"border: 1px solid #646464; width: 10.3368%; padding: 5px; text-align: left; vertical-align: top;\">reduziert die Notwendigkeit von Annotationen f\u00fcr Doku<\/p>\n<p>kombiniert manuell geschriebene Doku und generierte Doku<\/p>\n<p>f\u00fcr Spring \/ Spring Boot Projekte<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h1>Zusammenfassung<\/h1>\n<p>Warum schreibt ihr eine API? Vermutlich damit sie jemand (anderes) verwendet und einen Nutzen aus dieser Verwendung generiert. Wie soll jedoch eure API verwendet werden, wenn nicht klar ist, wie sie funktioniert. Wie haben uns in diesem Artikel vier verschiedenen Werkzeuge angeschaut, um im Umfeld von Java-Projekten eine REST-API f\u00fcr andere gut lesbar oder sogar erfahrbar zu dokumentieren.<\/p>\n<p>Die Seiten der jeweiligen Projekte bieten sehr detaillierte und umfangreiche Dokumentationen mit reichlich Beispielen, wie sie angewendet werden k\u00f6nnen. Aus diesem Grund haben wir auf eigene Implementierungsbeispiele verzichtet.<\/p>\n<p>Wir hoffen euch ein wenig bei der Auswahl des geeigneten Werkzeugs unterst\u00fctzt zu haben. Setzt ihr vielleicht noch andere Tools ein, die hier nicht auftauchen, aber viiieeel besser sind? Dann lasst es uns wissen.<\/p>\n<p>Eure Spa\u00df-Coder<\/p>\n<p>Dieser Artikel basiert neben unseren Erfahrungen auf den Ausf\u00fchrungen aus:<\/p>\n<ul>\n<li>[1] http:\/\/www.agilemanifesto.org\/iso\/de\/<\/li>\n<li>[2] http:\/\/www.java-doc.de\/<\/li>\n<li>[3] http:\/\/docs.spring.io\/spring-restdocs\/docs\/current\/reference\/html5\/<\/li>\n<li>[4] http:\/\/jsondoc.org\/<\/li>\n<li>[5] http:\/\/swagger.io\/<\/li>\n<li>[6] http:\/\/springfox.github.io\/springfox\/<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Hallo Spa\u00df-Coder. Das agile Manifesto[1]\u00a0 besagt unter anderem &#8222;Funktionierende Software mehr als umfassende Dokumentation&#8222;. Damit ist jedoch nicht gemeint, dass ein Softwareprojekt keine Dokumentation enthalten sollte. Wer hat selbst schon einmal versucht eine API zu verwenden und sich dann m\u00fchsam durch Versuch und Irrtum sehr z\u00e4h dem gew\u00fcnschten Ergebnis gen\u00e4hert? Oder eine f\u00fcnf Jahre alte [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":1268,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[22],"tags":[],"_links":{"self":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/1165"}],"collection":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/comments?post=1165"}],"version-history":[{"count":31,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/1165\/revisions"}],"predecessor-version":[{"id":1269,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/1165\/revisions\/1269"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/media\/1268"}],"wp:attachment":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/media?parent=1165"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/categories?post=1165"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/tags?post=1165"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}