{"id":10982,"date":"2016-12-15T15:40:48","date_gmt":"2016-12-15T13:40:48","guid":{"rendered":"https:\/\/blog.zhaw.ch\/icclab\/?p=10982"},"modified":"2019-08-05T14:35:27","modified_gmt":"2019-08-05T12:35:27","slug":"rapid-api-generation-with-ramses","status":"publish","type":"post","link":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/","title":{"rendered":"Rapid API generation with Ramses"},"content":{"rendered":"\n<p>by <a href=\"https:\/\/blog.zhaw.ch\/icclab\/josef-spillner\/\">Josef Spillner<\/a><\/p>\n\n\n<p>Rapid service prototyping, cloud application prototyping and API prototyping are closely related techniques which share a common goal: To get a first working prototype designed, implemented and placed online quickly, with small effort and with little headache over tooling concerns. The approaches in this area are still emerging and thus often ad-hoc or even immature. Several prototyping frameworks do nevertheless show a potential to become part of serious engineering workflows. In this post, the <a href=\"http:\/\/ramses.tech\/\">Ramses<\/a> framework will be presented and evaluated regarding this goal.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10983 aligncenter\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid.jpg\" alt=\"\" width=\"446\" height=\"267\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid.jpg 446w, https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid-300x180.jpg 300w\" sizes=\"auto, (max-width: 446px) 100vw, 446px\" \/><\/p>\n<p><!--more--><\/p>\n<p>Ramses mixes the <a href=\"https:\/\/trypyramid.com\/\">Pyramid<\/a> web framework for Python applications with <a href=\"http:\/\/raml.org\/\">RAML<\/a> service descriptions, a database, a search engine and several additional modules to achieve a description-to-service transformation. The transformation considers the schemas linked to the description and thus allows for structured data manipulation according to the CRUD (Create, Read, Update, Delete) paradigm. Both relational databases (through SQLAlchemy) and document databases (i.e. MongoDB) are supported choices, whereas the search engine is fixed as ElasticSearch.<\/p>\n<p>In a level model, the first level is application prototyping where the application can manage its data. The second level is to offer a (possibly remotely invocable) API. The third level is to lift the entire construct to the (micro-)service level which asks for uniform descriptions and interfaces as well as discoverability. In this model, Ramses focuses on the second level with some aspects from the third one. Hence, the focus of this post is equally on API generation as part of a more holistic service prototyping concern. The <a href=\"http:\/\/ramses.tech\/\">website of Ramses<\/a> is lacking in several regards. The prominently shown example is only an excerpt of the actual effort to get a service going. The framework is open source with a somewhat hidden reference to the <a href=\"https:\/\/github.com\/ramses-tech\/\">associated Git repository<\/a>. And finally, the published <a href=\"https:\/\/ramses.readthedocs.io\/en\/stable\/getting_started.html\">instructions<\/a> assume a prior installation and configuration of both a database server and an ElasticSearch instance. Hence, this post also aims to improve and offer more streamlined instructions suitable for auto-didactic learning and results reproduction. All instructions have been tested on a Xubuntu 16.04 virtual machine after a default installation on an 8 GB disk image.<\/p>\n<p>First things first: Installation of the prerequisites. The line shown below assumes a minimal environment with an embedded database. Alternatively, replace <em>sqlite3<\/em> with <em>mongodb<\/em> or with the two packages <em>postgresql-server-dev-9.5 postgresql-9.5<\/em>.<\/p>\n<pre>sudo apt-get install python-pip virtualenv git vim elasticsearch sqlite3 curl<\/pre>\n<p>If you use PostgreSQL, do not forget to configure a proper database.<\/p>\n<pre>sudo su -c psql postgres\n# CREATE USER ramses WITH PASSWORD 'ramses' SUPERUSER;\n# CREATE DATABASE ramses OWNER ramses<\/pre>\n<p>Furthermore, ElasticSearch does not start by default on Ubuntu, and the <a href=\"http:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/2.1\/setup-service.html\">instructions<\/a> are not working out of the box due to a legacy SysV init vs. Systemd compatibility issue. Instead, the following instructions work by allowing the daemon to start before enabling the Systemd unit.<\/p>\n<pre>sudo sed -i -e 's\/^#START_DAEMON\/START_DAEMON\/g' \/etc\/default\/elasticsearch\nsudo \/bin\/systemctl daemon-reload\nsudo \/bin\/systemctl enable elasticsearch.service\nsudo \/bin\/systemctl start elasticsearch.service<\/pre>\n<p>Now, the prerequisites are set. Confirm with <em>netstat -ltp<\/em> that both ElasticSearch (on ports 9200 and 9300) and the database server (if not embedded, e.g. port 5432 for PostgreSQL) are running. Then, simply follow the instructions as found in the <a href=\"https:\/\/github.com\/ramses-tech\/ramses\/blob\/0d789c4d32914f8a75087b93681ab96ad538ca16\/docs\/source\/getting_started.rst\">latest development branch<\/a> in Git. They will lead to a working example project using Ramses.<\/p>\n<pre>mkdir my_project\ncd my_project\nvirtualenv venv\nsource venv\/bin\/activate\npip install ramses # choose MongoDB or SQLAlchemy\npcreate -s ramses_starter . # note trailing dot; configure here\npserve local.ini<\/pre>\n<p>Before executing the last command, modify the configuration file local.ini according to your database choice. Use one of the two lines given below; note the (odd but necessary) fourth slash for SQLite. Also take a look at the service description file (<em>api.raml<\/em> and <em>items.json<\/em> for the schema) to get a glimpse at what the service will offer.<\/p>\n<pre>sqlalchemy.url = postgresql:\/\/ramses:ramses@localhost:5432\/ramses\nsqlalchemy.url = sqlite:\/\/\/\/tmp\/test.sqlite<\/pre>\n<p>There should be no error messages during the execution of these commands. Notice how <em>virtualenv<\/em> is used to shield the system from additional dependencies which will be installed. Overall, the folder will be about 50 MB in size. As the last command will take your terminal, open a second session and again verify with <em>netstat -ltp<\/em> that Ramses is indeed running on the default port 6543. Furthermore, you can verify that that the data structures have been created, for instance by running <em>\\d<\/em> in PostgreSQL (connect with <em>psql &#8211;host=localhost &#8211;user=ramses &#8211;password ramses<\/em>) or <em>.tables<\/em> in SQLite (connect with <em>sqlite3 \/tmp\/test.sqlite<\/em>).<\/p>\n<p>Now you can read and write data through the HTTP API.<\/p>\n<pre>curl http:\/\/localhost:6543\/api\/items\ncurl -H \"Content-Type: application\/json\" -X POST -d '{\"name\": \"Abu Simbel\", \"id\": 19, \"description\": \"Nubia\"}' http:\/\/localhost:6543\/api\/items<\/pre>\n<p>The example API is ready and can now be customised. An additional step towards actual service prototyping would be the deployment of the whole project. The options would be: (1) placing everything into a virtual machine or container, or (2) deploying as a Python project within a PaaS with database and search engine offered as complementary services. Unfortunately, (2) is not widely available. Hence, this post informs about (1) using a container. One basic consideration is whether to continue using <em>virtualenv<\/em> given that containers also isolate. The web is full of posts <a href=\"https:\/\/hynek.me\/articles\/virtualenv-lives\/\">for<\/a> and <a href=\"http:\/\/www.markbetz.net\/2014\/01\/17\/python-if-you-have-docker-do-you-need-virtualenv\/\">against<\/a> it. Given that the environments produced by <em>virtualenv<\/em> are not portable, i.e. the generated scripts contain hardcoded paths, it appears to be less troublesome to just do away with them.<\/p>\n<p>The following represents a Dockerfile which launches both the generated API and ElasticSearch which, unfortunately, is not an optional service for Ramses. Furthermore, given the issue with Systemd initialisation, a crude but simple workaround for launching both services is used.<\/p>\n<pre>FROM python\n\nRUN apt-get update\nRUN apt-get -y install elasticsearch\n\nADD . \/opt\/ramses\nRUN rm -rf \/opt\/ramses\/venv\nRUN pip install ramses\nRUN cd \/opt\/ramses &amp;&amp; pip install -r requirements.txt &amp;&amp; pip install nefertari_sqla\n\nEXPOSE 6543\n\nCMD cd \/opt\/ramses &amp;&amp; (su -s \/bin\/bash -c \/usr\/share\/elasticsearch\/bin\/elasticsearch elasticsearch &amp;); sleep 20 &amp;&amp; pserve local.ini<\/pre>\n<p>Build the container with <em>sudo docker build -t ramsesdocker .<\/em> and run it with <em>sudo docker run -ti -p6543:6543 ramsesdocker<\/em>. Note that the container will execute fine locally but may not easily run on several container platforms due to security concerns. On OpenShift, it starts despite a security warning but fails due to <em>su<\/em> expecting a terminal. One workaround is to launch elasticsearch without the use of <em>su<\/em>. This requires \/usr\/share\/elasticsearch\/data (an alias to \/var\/lib\/elasticsearch) to be world-writeable. Furthermore, the <em>sleep 20<\/em> part is brittle and perhaps over- or underestimating the launch time of ElasticSearch; a proper port availability notification or polling would be more robust. Installing net-tools and running <em>netstat -ltpn<\/em> during the startup sequence helps with debugging. With these changes, the container has been verified to work successfully in OpenShift (e.g. at <a href=\"https:\/\/appuio.ch\/\">APPUiO<\/a>).<\/p>\n<p>Overall, the process to get a service done quickly takes several hours with Ramses as it is documented and presumably less than half an hour with the provided instructions. We are eager to hear confirmations, rebuttals and other evaluations of this tool as well as reports about related prototyping tools.<\/p><div class=\"pt-sm\">Schlagw\u00f6rter: <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/api\/\">api<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/docker\/\">docker<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/howto\/\">howto<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/python\/\">Python<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/raml\/\">raml<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/rapid-prototyping\/\">rapid prototyping<\/a><br><\/div>","protected":false},"excerpt":{"rendered":"<p>Rapid service prototyping, cloud application prototyping and API prototyping are closely related techniques which share a common goal: To get a first working prototype designed, implemented and placed online quickly, with small effort and with little headache over tooling concerns. The approaches in this area are still emerging and thus often ad-hoc or even immature. [&hellip;]<\/p>\n","protected":false},"author":486,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1],"tags":[829,484,181,273,830,727],"features":[],"class_list":["post-10982","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-api","tag-docker","tag-howto","tag-python","tag-raml","tag-rapid-prototyping"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Rapid API generation with Ramses - Service Engineering (ICCLab &amp; SPLab)<\/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.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Rapid API generation with Ramses\" \/>\n<meta property=\"og:description\" content=\"Rapid service prototyping, cloud application prototyping and API prototyping are closely related techniques which share a common goal: To get a first working prototype designed, implemented and placed online quickly, with small effort and with little headache over tooling concerns. The approaches in this area are still emerging and thus often ad-hoc or even immature. [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/\" \/>\n<meta property=\"og:site_name\" content=\"Service Engineering (ICCLab &amp; SPLab)\" \/>\n<meta property=\"article:published_time\" content=\"2016-12-15T13:40:48+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-08-05T12:35:27+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid.jpg\" \/>\n<meta name=\"author\" content=\"icclab\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"icclab\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/\"},\"author\":{\"name\":\"icclab\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/045c6bde7e681e689e4fc051d8932563\"},\"headline\":\"Rapid API generation with Ramses\",\"datePublished\":\"2016-12-15T13:40:48+00:00\",\"dateModified\":\"2019-08-05T12:35:27+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/\"},\"wordCount\":1016,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid.jpg\",\"keywords\":[\"api\",\"docker\",\"howto\",\"Python\",\"raml\",\"rapid prototyping\"],\"articleSection\":[\"*.*\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/\",\"name\":\"Rapid API generation with Ramses - Service Engineering (ICCLab &amp; SPLab)\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid.jpg\",\"datePublished\":\"2016-12-15T13:40:48+00:00\",\"dateModified\":\"2019-08-05T12:35:27+00:00\",\"author\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/045c6bde7e681e689e4fc051d8932563\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#primaryimage\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid.jpg\",\"contentUrl\":\"https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid.jpg\",\"width\":446,\"height\":267},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\/\/blog.zhaw.ch\/icclab\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Rapid API generation with Ramses\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#website\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/\",\"name\":\"Service Engineering (ICCLab &amp; SPLab)\",\"description\":\"A Blog of the ZHAW Zurich University of Applied Sciences\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.zhaw.ch\/icclab\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/045c6bde7e681e689e4fc051d8932563\",\"name\":\"icclab\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/7b13169e03783f50e96b96fa2ff222b9c530d13c3125f077c7c44f729b857a51?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/7b13169e03783f50e96b96fa2ff222b9c530d13c3125f077c7c44f729b857a51?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/7b13169e03783f50e96b96fa2ff222b9c530d13c3125f077c7c44f729b857a51?s=96&d=mm&r=g\",\"caption\":\"icclab\"},\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/author\/icclab\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Rapid API generation with Ramses - Service Engineering (ICCLab &amp; SPLab)","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.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/","og_locale":"en_US","og_type":"article","og_title":"Rapid API generation with Ramses","og_description":"Rapid service prototyping, cloud application prototyping and API prototyping are closely related techniques which share a common goal: To get a first working prototype designed, implemented and placed online quickly, with small effort and with little headache over tooling concerns. The approaches in this area are still emerging and thus often ad-hoc or even immature. [&hellip;]","og_url":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/","og_site_name":"Service Engineering (ICCLab &amp; SPLab)","article_published_time":"2016-12-15T13:40:48+00:00","article_modified_time":"2019-08-05T12:35:27+00:00","og_image":[{"url":"https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid.jpg","type":"","width":"","height":""}],"author":"icclab","twitter_card":"summary_large_image","twitter_misc":{"Written by":"icclab","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#article","isPartOf":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/"},"author":{"name":"icclab","@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/045c6bde7e681e689e4fc051d8932563"},"headline":"Rapid API generation with Ramses","datePublished":"2016-12-15T13:40:48+00:00","dateModified":"2019-08-05T12:35:27+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/"},"wordCount":1016,"commentCount":0,"image":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid.jpg","keywords":["api","docker","howto","Python","raml","rapid prototyping"],"articleSection":["*.*"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/","url":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/","name":"Rapid API generation with Ramses - Service Engineering (ICCLab &amp; SPLab)","isPartOf":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#primaryimage"},"image":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid.jpg","datePublished":"2016-12-15T13:40:48+00:00","dateModified":"2019-08-05T12:35:27+00:00","author":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/045c6bde7e681e689e4fc051d8932563"},"breadcrumb":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#primaryimage","url":"https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid.jpg","contentUrl":"https:\/\/blog.zhaw.ch\/icclab\/files\/2016\/12\/pyramid.jpg","width":446,"height":267},{"@type":"BreadcrumbList","@id":"https:\/\/blog.zhaw.ch\/icclab\/rapid-api-generation-with-ramses\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/blog.zhaw.ch\/icclab\/"},{"@type":"ListItem","position":2,"name":"Rapid API generation with Ramses"}]},{"@type":"WebSite","@id":"https:\/\/blog.zhaw.ch\/icclab\/#website","url":"https:\/\/blog.zhaw.ch\/icclab\/","name":"Service Engineering (ICCLab &amp; SPLab)","description":"A Blog of the ZHAW Zurich University of Applied Sciences","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.zhaw.ch\/icclab\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/045c6bde7e681e689e4fc051d8932563","name":"icclab","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/7b13169e03783f50e96b96fa2ff222b9c530d13c3125f077c7c44f729b857a51?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/7b13169e03783f50e96b96fa2ff222b9c530d13c3125f077c7c44f729b857a51?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/7b13169e03783f50e96b96fa2ff222b9c530d13c3125f077c7c44f729b857a51?s=96&d=mm&r=g","caption":"icclab"},"url":"https:\/\/blog.zhaw.ch\/icclab\/author\/icclab\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/10982","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/users\/486"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/comments?post=10982"}],"version-history":[{"count":6,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/10982\/revisions"}],"predecessor-version":[{"id":12520,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/10982\/revisions\/12520"}],"wp:attachment":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/media?parent=10982"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/categories?post=10982"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/tags?post=10982"},{"taxonomy":"features","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/features?post=10982"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}