{"id":286,"date":"2013-04-10T10:56:03","date_gmt":"2013-04-10T08:56:03","guid":{"rendered":"http:\/\/blog.zeit.de\/dev\/?p=286"},"modified":"2015-09-17T11:24:00","modified_gmt":"2015-09-17T09:24:00","slug":"zon-api-ist-quelloffen","status":"publish","type":"post","link":"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/","title":{"rendered":"ZON-API ist quelloffen"},"content":{"rendered":"<p id=\"internal-source-marker_0.00903180235648704\" dir=\"ltr\">Seit dem Launch der Beta-Phase hat unsere <a href=\"http:\/\/developer.zeit.de\/index\/\">API<\/a> nun mehrere Millionen Requests beantwortet. Wir haben spannende Projekte gesehen und viel konstruktives Feedback erhalten. Ein \u00f6ffentliches Bugtracking und der neue Twitterchannel <a href=\"https:\/\/twitter.com\/zeitonline_dev\">@zeitonline_dev<\/a> waren die ersten Schritte, dieses Potenzial zu nutzen. Nun m\u00f6chten wir interessierten Entwicklern einen Einblick in unsere Schnittstelle geben. Alle <a href=\"http:\/\/github.com\/ZeitOnline\/content-api\">Sourcen der API<\/a> sind ab sofort auf Github verf\u00fcgbar. Die Architektur erl\u00e4utern wir hier kurz.<\/p>\n<p dir=\"ltr\"><!--more--><\/p>\n<h3 dir=\"ltr\"><strong>Vom CMS zur API zur App<\/strong><\/h3>\n<p dir=\"ltr\">Der Publikationsprozess unseres Content Management Systems st\u00f6\u00dft eine Reihe von Aktionen an, die den Artikel auf unterschiedlichen Kan\u00e4len verf\u00fcgbar machen. F\u00fcr die API werden die Rohdaten des Artikels mit XSL transformiert und via HTTP an den API-Suchserver gesendet. Dies realisieren wir mit <a href=\"http:\/\/lucene.apache.org\/solr\/index.html\">Solr<\/a>, einem Projekt der Apache Foundation. Solr basiert zum gr\u00f6\u00dften Teil auf Lucene Bibliotheken und bietet m\u00e4chtige Features zur Volltextsuche \u00fcber gro\u00dfe Datenmengen. Auch in anderen Bereichen von ZEIT ONLINE wird mit Solr-Technologie gearbeitet, so dass die Wahl f\u00fcr das API-Projekt nahe lag. Die API benutzt f\u00fcr Suchanfragen den <a href=\"http:\/\/wiki.apache.org\/solr\/ExtendedDisMax\">ExtendedDisMax Query Parser<\/a> von Solr. Dieser ist bez\u00fcglich der Syntax sehr fehlertolerant und gut geeignet, Benutzereingaben direkt zu verarbeiten. Er unterst\u00fctzt die volle Suchsyntax und kann spezifische Queries mit boolschen Verkn\u00fcpfungen, Feldselektoren oder Zeitspannen verarbeiten.<\/p>\n<p dir=\"ltr\">Die sogenannte Facettierung ist ein weiteres Feature von Solr, das f\u00fcr Gruppierung und Quantifizierung von Inhalten n\u00fctzlich ist. Eine Facette eines Feldes zeigt an, welcher Wertebereich innerhalb der Suchanfrage vorkommt und wie oft ein Wert vertreten ist. Eine Facette ist also eine Untermenge der eigentlichen Query.<\/p>\n<p dir=\"ltr\">Solr bildet keine Relationen zwischen Elementen ab. Deshalb haben wir uns f\u00fcr eine Hybrid-L\u00f6sung entschieden: Der Suchserver indexiert Artikeltexte und konstante IDs der zugeh\u00f6rigen Metadaten-Objekte. Die Metadaten-Objekte selbst werden in einer relationalen Datenbank unter der entsprechenden ID als Schl\u00fcssel gespeichert. Dies ist zum Beispiel die Kategorie und lexikalische Schreibweise eines Schlagworts. Durch diese Trennung k\u00f6nnen globale \u00c4nderungen an Metadaten durchgef\u00fchrt werden, ohne dass alle betroffenen Artikel neu indexiert werden m\u00fcssen.<\/p>\n<p dir=\"ltr\">Ein HTTP-Request an die API wird von einer Middleware auf Basis des <a href=\"http:\/\/flask.pocoo.org\/\">Web Frameworks Flask<\/a> beantwortet. Die Parameter und deren Werte werden auf G\u00fcltigkeit \u00fcberpr\u00fcft und der angegebene API-Key verifiziert. War die Anfrage valide, muss sie zun\u00e4chst f\u00fcr den Solr \u00fcbersetzt werden, da dessen <a href=\"http:\/\/www.ics.uci.edu\/~fielding\/pubs\/dissertation\/rest_arch_style.htm\">REST<\/a>-Interface leicht von dem unserer API abweicht.<\/p>\n<p dir=\"ltr\">Die Maskierung und Reduktion der umfangreichen M\u00f6glichkeiten von Solr soll die Bedienung der API vereinfachen und ist dem Datenschema angepasst. Als Ausgabeformat setzen wir auf JSON. Es ist schemafrei, wird von den meisten Sprachen und Plattformen unterst\u00fctzt und ist auch in Rohform noch gut lesbar.<\/p>\n<h3 dir=\"ltr\"><strong>Happy Developing<\/strong><\/h3>\n<p dir=\"ltr\">Wir freuen uns \u00fcber jeden Fork,\u00a0 jeden Pull-Request und auf einen regen Austausch. Unser Code unterliegt der <a href=\"http:\/\/en.wikipedia.org\/wiki\/BSD_licenses#2-clause_license_.28.22Simplified_BSD_License.22_or_.22FreeBSD_License.22.29\">BSD-Lizenz<\/a>, da diese Entwicklern alle Freiheiten gibt, Code zu ver\u00e4ndern und zu redistribuieren. \u00dcber einen kurzen Hinweis, wo und wie unser API-Code zum Einsatz kommt, w\u00fcrden wir uns freuen.<\/p>\n<p dir=\"ltr\">Wir werden unsere API selbstverst\u00e4ndlich weiter verbessern. Auch Bugreports und Featurerequests sind weiterhin willkommen.<\/p>\n<p dir=\"ltr\"><strong>Links zum Thema<\/strong><\/p>\n<ul>\n<li>\u00a0<a href=\"http:\/\/github.com\/ZeitOnline\/content-api\">Content-API auf Github<\/a><\/li>\n<li><a href=\"http:\/\/lucene.apache.org\/solr\/index.html\">Apache Solr<\/a><\/li>\n<li><a href=\"http:\/\/flask.pocoo.org\/\">Flask Web Framework<\/a><\/li>\n<li><a href=\"http:\/\/www.ics.uci.edu\/~fielding\/pubs\/dissertation\/rest_arch_style.htm\">Representational State Transfer<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Seit dem Launch der Beta-Phase hat unsere API nun mehrere Millionen Requests beantwortet. Wir haben spannende Projekte gesehen und viel konstruktives Feedback erhalten. Ein \u00f6ffentliches Bugtracking und der neue Twitterchannel @zeitonline_dev waren die ersten Schritte, dieses Potenzial zu nutzen. Nun m\u00f6chten wir interessierten Entwicklern einen Einblick in unsere Schnittstelle geben. Alle Sourcen der API sind [&hellip;]<\/p>\n","protected":false},"author":398,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[17446],"tags":[],"class_list":["post-286","post","type-post","status-publish","format-standard","hentry","category-api"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>ZON-API ist quelloffen - Dev-Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"ZON-API ist quelloffen - Dev-Blog\" \/>\n<meta property=\"og:description\" content=\"Seit dem Launch der Beta-Phase hat unsere API nun mehrere Millionen Requests beantwortet. Wir haben spannende Projekte gesehen und viel konstruktives Feedback erhalten. Ein \u00f6ffentliches Bugtracking und der neue Twitterchannel @zeitonline_dev waren die ersten Schritte, dieses Potenzial zu nutzen. Nun m\u00f6chten wir interessierten Entwicklern einen Einblick in unsere Schnittstelle geben. Alle Sourcen der API sind [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/\" \/>\n<meta property=\"og:site_name\" content=\"Dev-Blog\" \/>\n<meta property=\"article:published_time\" content=\"2013-04-10T08:56:03+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-09-17T09:24:00+00:00\" \/>\n<meta name=\"author\" content=\"ndrebenstedt\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Geschrieben von\" \/>\n\t<meta name=\"twitter:data1\" content=\"ndrebenstedt\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"3\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/\",\"url\":\"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/\",\"name\":\"ZON-API ist quelloffen - Dev-Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zeit.de\/dev\/#website\"},\"datePublished\":\"2013-04-10T08:56:03+00:00\",\"dateModified\":\"2015-09-17T09:24:00+00:00\",\"author\":{\"@id\":\"https:\/\/blog.zeit.de\/dev\/#\/schema\/person\/0753c6cb41310deffd58c2da973aa440\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\/\/blog.zeit.de\/dev\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"ZON-API ist quelloffen\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.zeit.de\/dev\/#website\",\"url\":\"https:\/\/blog.zeit.de\/dev\/\",\"name\":\"Dev-Blog\",\"description\":\"Entwicklungsblog von ZEIT ONLINE\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.zeit.de\/dev\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"de\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.zeit.de\/dev\/#\/schema\/person\/0753c6cb41310deffd58c2da973aa440\",\"name\":\"ndrebenstedt\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/blog.zeit.de\/dev\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/1c0255fef2eea28736a0708b20dfcd57af63108fecb4f0effe42aadb8739b712?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/1c0255fef2eea28736a0708b20dfcd57af63108fecb4f0effe42aadb8739b712?s=96&d=mm&r=g\",\"caption\":\"ndrebenstedt\"},\"url\":\"https:\/\/blog.zeit.de\/dev\/author\/ndrebenstedt\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"ZON-API ist quelloffen - Dev-Blog","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:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/","og_locale":"de_DE","og_type":"article","og_title":"ZON-API ist quelloffen - Dev-Blog","og_description":"Seit dem Launch der Beta-Phase hat unsere API nun mehrere Millionen Requests beantwortet. Wir haben spannende Projekte gesehen und viel konstruktives Feedback erhalten. Ein \u00f6ffentliches Bugtracking und der neue Twitterchannel @zeitonline_dev waren die ersten Schritte, dieses Potenzial zu nutzen. Nun m\u00f6chten wir interessierten Entwicklern einen Einblick in unsere Schnittstelle geben. Alle Sourcen der API sind [&hellip;]","og_url":"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/","og_site_name":"Dev-Blog","article_published_time":"2013-04-10T08:56:03+00:00","article_modified_time":"2015-09-17T09:24:00+00:00","author":"ndrebenstedt","twitter_card":"summary_large_image","twitter_misc":{"Geschrieben von":"ndrebenstedt","Gesch\u00e4tzte Lesezeit":"3\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/","url":"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/","name":"ZON-API ist quelloffen - Dev-Blog","isPartOf":{"@id":"https:\/\/blog.zeit.de\/dev\/#website"},"datePublished":"2013-04-10T08:56:03+00:00","dateModified":"2015-09-17T09:24:00+00:00","author":{"@id":"https:\/\/blog.zeit.de\/dev\/#\/schema\/person\/0753c6cb41310deffd58c2da973aa440"},"breadcrumb":{"@id":"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.zeit.de\/dev\/zon-api-ist-quelloffen\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/blog.zeit.de\/dev\/"},{"@type":"ListItem","position":2,"name":"ZON-API ist quelloffen"}]},{"@type":"WebSite","@id":"https:\/\/blog.zeit.de\/dev\/#website","url":"https:\/\/blog.zeit.de\/dev\/","name":"Dev-Blog","description":"Entwicklungsblog von ZEIT ONLINE","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.zeit.de\/dev\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"de"},{"@type":"Person","@id":"https:\/\/blog.zeit.de\/dev\/#\/schema\/person\/0753c6cb41310deffd58c2da973aa440","name":"ndrebenstedt","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/blog.zeit.de\/dev\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/1c0255fef2eea28736a0708b20dfcd57af63108fecb4f0effe42aadb8739b712?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1c0255fef2eea28736a0708b20dfcd57af63108fecb4f0effe42aadb8739b712?s=96&d=mm&r=g","caption":"ndrebenstedt"},"url":"https:\/\/blog.zeit.de\/dev\/author\/ndrebenstedt\/"}]}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blog.zeit.de\/dev\/wp-json\/wp\/v2\/posts\/286","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.zeit.de\/dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.zeit.de\/dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.zeit.de\/dev\/wp-json\/wp\/v2\/users\/398"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.zeit.de\/dev\/wp-json\/wp\/v2\/comments?post=286"}],"version-history":[{"count":18,"href":"https:\/\/blog.zeit.de\/dev\/wp-json\/wp\/v2\/posts\/286\/revisions"}],"predecessor-version":[{"id":717,"href":"https:\/\/blog.zeit.de\/dev\/wp-json\/wp\/v2\/posts\/286\/revisions\/717"}],"wp:attachment":[{"href":"https:\/\/blog.zeit.de\/dev\/wp-json\/wp\/v2\/media?parent=286"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.zeit.de\/dev\/wp-json\/wp\/v2\/categories?post=286"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.zeit.de\/dev\/wp-json\/wp\/v2\/tags?post=286"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}