{"id":23,"date":"2007-07-24T19:48:08","date_gmt":"2007-07-24T19:48:08","guid":{"rendered":"http:\/\/euve3303.vserver.de\/stefan\/blog\/?p=26"},"modified":"2007-07-24T19:48:08","modified_gmt":"2007-07-24T19:48:08","slug":"contract-first","status":"publish","type":"post","link":"https:\/\/cogito-ergo-blog.de\/blog\/2007\/07\/24\/contract-first\/","title":{"rendered":"Contract first?"},"content":{"rendered":"<p>Gestern abend bin ich zuf\u00e4llig \u00fcber eins der Sub-Projekte von Spring gestolpert: <a href=\"http:\/\/static.springframework.org\/spring-ws\/site\/\">Spring-WS<\/a> (Spring WebServices). Beim Lesen der Dokumentation stach mir die Behauptung ins Auge &quot;Best Practice made easier&quot;, gemeint ist ein Contract-First Ansatz und das Arbeiten direkt mit den XML-Nachrichten.<\/p>\n<p>In einem eigenen <a href=\"http:\/\/static.springframework.org\/spring-ws\/site\/reference\/html\/why-contract-first.html\">Abschnitt<\/a> wird ausgef\u00fchrt, warum (speziell im Falle von WebServices) der Contract-First Ansatz der Bessere ist:<\/p>\n<p>Zum einen lassen die Type-Definitionen mit XML Schema Konstruktionen zu, die in Java (um diese Sprache geht es hier ;-)) gar nicht m\u00f6glich sind.<\/p>\n<p>Zum anderen lassen bestimmte Sprachkonstrukte, wie zyklische Bez\u00fcge nicht einfach so nach XML abbilden.<\/p>\n<p>Deshalb, so die Schlussfolgerung, sei es das Beste, direkt mit den XML-Nachrichten zu arbeiten. Hierf\u00fcr gibt&#8217;s ja schlie\u00dflich eine Reihe von APIs mit denen sich das einfach bewerkstelligen l\u00e4\u00dft.<\/p>\n<p>Als kr\u00f6nender Abschluss wird, im Falle einer neuen Version des Contracts und damit anderer XML-Nachrichten, auf die M\u00f6glichkeit verwiesen, diese unter Umst\u00e4nden ganz einfach mit XSLT wieder auf die &quot;Old-Style&quot;-Nachricht abzubilden, und somit m\u00fc\u00dfte man nicht mal eine neue Java-Implementierung schreiben.<\/p>\n<h3>Geht&#8217;s noch &#8230;<\/h3>\n<p>In der Tat, um mal beim letzten Punkt anzufangen, man braucht keine neue Java-Implementierung und auch kein neues Java-Interface, aber daf\u00fcr ein XSLT-Stylesheet. Und wenn das dann nicht so arbeitet, wie man gedacht hat, dann baucht man einen Debugger f\u00fcr die Transformation-Engine, damit man sieht wo es schief geht &#8230;.<\/p>\n<p><!--more--><\/p>\n<h3>WebServices als einfache Middleware<\/h3>\n<p>Man kann WebServices auch anders sehen: n\u00e4mlich als eine weitere M\u00f6glichkeit verteiltes Rechnen (am besten \u00fcber System- und Sprachgrenzen hinaus) zu erm\u00f6glichen. Dieser Anspruch wird ja auch immer wieder propagiert. Wenn das allerdings der Anspruch sein soll, dann bin ich als System-Designer oder auch als Application-Developer reichlich wenig daran interressiert, wie das Wire-Protokoll meiner Middleware funktioniert. Oder interessiert sich irgendjemand so genau wie Java RMI auf der Leitung funktioniert, oder wie sich (fr\u00fcher) ein Corba-Client per IIOP mit seinem Server unterhalten hat?<\/p>\n<p>Das interessiert keinen Menschen, weil es niemand interessieren mu\u00df! Man benutzt es einfach. Es gibt klare Regeln welche Typen wie auf der Leitung zu kodieren sind und es gibt dar\u00fcber hinaus ein (einigermassen) eindeutig definierten Sprachmapping, das die m\u00f6glichen Konstrukte eindeutig in die unterschiedlichen Sprachen abbildet.<\/p>\n<h3>XSD als Typbeschreibung<\/h3>\n<p>Wenn also XML Schema so schwierig in ein Sprachmapping zu \u00fcberf\u00fchren ist, dann sollte man es am besten einfach gar nicht verwenden! Oder so weit einschr\u00e4nken, dass bestimmte Konstruktionen wie die bei Spring WS angef\u00fchrten &quot;Restrictions&quot; von Basistypen eben im Kontext von WebServices nicht erlaubt sind.<\/p>\n<p>Auch sind bestimmte Regeln die sich mit XML Schema konstruieren lassen im Rahmen einer Schema Types Definition in der Interfacebeschreibung eines WebServices eh am falschen Platz.<\/p>\n<h3>Contract ist nicht nur die technische Interfacebeschreibung<\/h3>\n<p>Der Contract (also Vertrag) geht sowieso immer \u00fcber die rein technische Beschreibung der Schnittstelle hinaus. In einem Vertrag muss man vielmehr auch die Rahmenbedigungen oder Spielregeln bekannt geben, wie man die Schnittstelle richtig benutzt. Was nutzt einem da eine Werteeinschr\u00e4nkung von z.B. 1 &#8211; 10 bei einem bestimmten Parameter einer Operation, wenn sich das nur im Schema und im Fehlerfall in einem Validierungfehler ausdr\u00fcckt? Nicht viel oder eigentlich gar nichts. Der die Schnittstelle benutzt wird dem Integer nicht ansehen, dass eine Einschr\u00e4nkung des Wertebereichs vorliegt. Sperrt man den Interger in eine Klasse ein, die den Wertebereich pr\u00fcft \/ erzwingt ist auch nicht viel gewonnen, das ist in der Praxis viel zu umst\u00e4ndlich.<\/p>\n<p>Besser es steht in der Dokumentation der Schnittstelle eben dabei, dass dieser Parameter diese und jene Semantik hat und deshalb in seinem Wertbereich eingeschr\u00e4nkt ist. Eine Pr\u00fcfung nimmt dabei auch besser die Businesslogik vor, schlie\u00dflich k\u00f6nnte es ja sein, dass diese auch von nicht Schems gecheckten WS-Clients gerufen wird. Die Businesslogik kann im Fehlerfall auch gleich eine aussagekr\u00e4ftige Fehlermeldung erzeugen, die beim Aufrufer allemal mehr Information hinterl\u00e4\u00dft als ein Schemavalidierungfehler.<\/p>\n<h3>Interoperable WebServices<\/h3>\n<p>Wenn also der Anspruch von WebService ist m\u00f6glichst interoperabel zu sein und es dazu ja sogar eigene Standards gibt, die WebServices interoperabler machen (WS-I <a target=\"_top\" href=\"http:\/\/www.ws-i.org\/Profiles\/BasicProfile-1.1.html#SOAP_encodingStyle_Attribute\">Basic Profile<\/a>), dann sollte das IMHO aber funktionieren ohne das ich mich mit den XML-Nachrichten herumschlagen muss.<\/p>\n<h3>Contract first!<\/h3>\n<p>Damit ich nicht missverstanden werde, ich bin von jeher ein \u00fcberzeugter Vertreter des &quot;Contract first&quot; Ansatzes. Zu Zeiten als es noch keine WebServices gab, war das aber auch viel einfacher: da gab es eine richtige Sprache, um technische Interfacebeschreibungen zu definieren. Diese Sprache las sich wie C++ oder Java war also von den meisten Techniker relativ leicht zu verstehen. Man konnte in dieser Sprache auch gleich die Dokumetation (wie bei JavaDoc) unterbringen und so neben der technischen auch eine semantische Beschreibung mitliefern. Man brauchte auch nicht unbedingt ein Werkzeug (ausser einem Editor) um selbst komplexe Interfaces zu definieren. Das Wunderding heisst: <b>IDL<\/b>.<\/p>\n<p>Ich kann mich nicht erinnern, dass ich auch nur ein Interface im Corba-Umfeld nicht mit der IDL begonnen h\u00e4tte. Eben Contract first! Und machen wir das mit XML Schema und WSDL, und dann bauen wir Implementierungen, die mit XPath-Expressions auf den XML Nachrichten &quot;herumoperieren&quot; und diese zuvor noch mit XSLT transformieren &#8230;<\/p>\n<p \/>\n<p>Sorry ist ein bisschen lang geworden, aber ich musste mich mal auslassen &#8230; \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Gestern abend bin ich zuf\u00e4llig \u00fcber eins der Sub-Projekte von Spring gestolpert: Spring-WS (Spring WebServices). Beim Lesen der Dokumentation stach mir die Behauptung ins Auge &quot;Best Practice made easier&quot;, gemeint ist ein Contract-First Ansatz und das Arbeiten direkt mit den &hellip; <a href=\"https:\/\/cogito-ergo-blog.de\/blog\/2007\/07\/24\/contract-first\/\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"_links":{"self":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/23"}],"collection":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/comments?post=23"}],"version-history":[{"count":0,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/23\/revisions"}],"wp:attachment":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/media?parent=23"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/categories?post=23"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/tags?post=23"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}