| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <meta name="description" content=""> | |
| <meta name="keywords" content="http, http, api, concepts, partial, conditional, optimistic locking, ETag, If-Match, If-None-Match"> | |
| <title> HTTP API concepts • Eclipse Ditto™ • a digital twin framework</title> | |
| <link rel="stylesheet" href="css/syntax.css"> | |
| <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" crossorigin="anonymous"> | |
| <link rel="stylesheet" href="css/modern-business.css"> | |
| <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" crossorigin="anonymous"> | |
| <link rel="stylesheet" href="css/customstyles.css"> | |
| <link rel="stylesheet" href="css/boxshadowproperties.css"> | |
| <link rel="stylesheet" href="css/theme-ditto.css"> | |
| <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700"> | |
| <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js" crossorigin="anonymous"></script> | |
| <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" crossorigin="anonymous"></script> | |
| <script src="//cdnjs.cloudflare.com/ajax/libs/anchor-js/2.0.0/anchor.min.js" crossorigin="anonymous"></script> | |
| <script src="js/toc.js"></script> | |
| <script src="js/customscripts.js"></script> | |
| <script type="application/ld+json"> | |
| { | |
| "@context": "http://schema.org", | |
| "@type": "Organization", | |
| "url": "https://eclipse.org/ditto/", | |
| "logo": "https://eclipse.org/ditto/images/ditto.svg" | |
| } | |
| </script> | |
| <link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16"> | |
| <link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32"> | |
| <link rel="icon" type="image/png" href="images/favicon-96x96.png" sizes="96x96"> | |
| <link rel="alternate" type="application/rss+xml" title="Eclipse Ditto Blog" href="https://www.eclipse.org/ditto/feed.xml"> | |
| <!-- Eclipse Foundation cookie consent: --> | |
| <link rel="stylesheet" type="text/css" href="//www.eclipse.org/eclipse.org-common/themes/solstice/public/stylesheets/vendor/cookieconsent/cookieconsent.min.css" /> | |
| <script src="//www.eclipse.org/eclipse.org-common/themes/solstice/public/javascript/vendor/cookieconsent/default.min.js"></script> | |
| <script> | |
| $(document).ready(function() { | |
| $("#tg-sb-link").click(function() { | |
| $("#tg-sb-sidebar").toggle(); | |
| $("#tg-sb-content").toggleClass('col-md-9'); | |
| $("#tg-sb-content").toggleClass('col-md-12'); | |
| $("#tg-sb-icon").toggleClass('fa-toggle-on'); | |
| $("#tg-sb-icon").toggleClass('fa-toggle-off'); | |
| }); | |
| }); | |
| </script> | |
| </head> | |
| <script> | |
| (function(w,d,s,l,i){ | |
| w[l]=w[l]||[]; | |
| w[l].push({'gtm.start': | |
| new Date().getTime(),event:'gtm.js'}); | |
| var f=d.getElementsByTagName(s)[0], | |
| j=d.createElement(s), | |
| dl=l!='dataLayer'?'&l='+l:''; | |
| j.async=true; | |
| j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl; | |
| f.parentNode.insertBefore(j,f); | |
| })(window,document,'script','dataLayer','GTM-5WLCZXC'); | |
| </script> | |
| <body> | |
| <!-- Navigation --> | |
| <nav class="navbar navbar-inverse navbar-fixed-top"> | |
| <div class="container topnavlinks"> | |
| <div class="navbar-header"> | |
| <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> | |
| <span class="sr-only">Toggle navigation</span> | |
| <span class="icon-bar"></span> | |
| <span class="icon-bar"></span> | |
| <span class="icon-bar"></span> | |
| </button> | |
| <a class="navbar-ditto-home" href="index.html"> <img src="images/ditto_allwhite_symbolonly.svg" class="ditto-navbar-symbol" alt="Home"> <img src="images/ditto_allwhite_textonly.svg" class="ditto-navbar-symbol-text" alt="Eclipse Ditto™"></a> | |
| </div> | |
| <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> | |
| <ul class="nav navbar-nav navbar-right"> | |
| <!-- toggle sidebar button --> | |
| <!--<li><a id="tg-sb-link" href="#"><i id="tg-sb-icon" class="fa fa-toggle-on"></i> Nav</a></li>--> | |
| <!-- entries without drop-downs appear here --> | |
| <li><a href="blog.html">Blog</a></li> | |
| <li><a href="intro-overview.html">Documentation</a></li> | |
| <li><a href="http-api-doc.html">HTTP API</a></li> | |
| <li><a href="sandbox.html">Sandbox</a></li> | |
| <li><a href="https://github.com/eclipse/ditto" target="_blank"> | |
| <img src="images/GitHub-Mark-Light-32px.png" alt="Sources at GitHub"> | |
| </a></li> | |
| <li><a href="https://github.com/eclipse/ditto-clients" target="_blank"> | |
| <img src="images/GitHub-Mark-Light-32px.png" alt="SDK sources at GitHub">SDKs | |
| </a></li> | |
| <li><a href="https://github.com/eclipse/ditto-examples" target="_blank"> | |
| <img src="images/GitHub-Mark-Light-32px.png" alt="Example sources at GitHub">examples | |
| </a></li> | |
| <!-- entries with drop-downs appear here --> | |
| <!-- conditional logic to control which topnav appears for the audience defined in the configuration file.--> | |
| <li class="dropdown"> | |
| <a href="#" class="dropdown-toggle" data-toggle="dropdown">Links<b class="caret"></b></a> | |
| <ul class="dropdown-menu"> | |
| <li><a href="https://projects.eclipse.org/projects/iot.ditto" target="_blank">Eclipse Ditto Project</a></li> | |
| <li><a href="https://www.eclipse.org/forums/index.php/f/364/" target="_blank">Forum</a></li> | |
| <li><a href="https://ci.eclipse.org/ditto/" target="_blank">Jenkins</a></li> | |
| <li><a href="https://dev.eclipse.org/mhonarc/lists/ditto-dev/" target="_blank">Mailing list archives</a></li> | |
| <li><a href="https://gitter.im/eclipse/ditto" target="_blank">Gitter.im chat</a></li> | |
| </ul> | |
| </li> | |
| <!--comment out this block if you want to hide search--> | |
| <li> | |
| <!--start search--> | |
| <div id="search-demo-container"> | |
| <input type="text" id="search-input" placeholder="search..."> | |
| <ul id="results-container"></ul> | |
| </div> | |
| <script src="//cdnjs.cloudflare.com/ajax/libs/simple-jekyll-search/0.0.9/jekyll-search.js" type="text/javascript"></script> | |
| <script type="text/javascript"> | |
| SimpleJekyllSearch.init({ | |
| searchInput: document.getElementById('search-input'), | |
| resultsContainer: document.getElementById('results-container'), | |
| dataSource: 'search.json', | |
| searchResultTemplate: '<li><a href="{url}" title="HTTP API concepts">{title}</a></li>', | |
| noResultsText: 'No results found.', | |
| limit: 10, | |
| fuzzy: true, | |
| }) | |
| </script> | |
| <!--end search--> | |
| </li> | |
| </ul> | |
| </div> | |
| </div> | |
| <!-- /.container --> | |
| </nav> | |
| <!-- Page Content --> | |
| <div class="container"> | |
| <div id="main"> | |
| <!-- Content Row --> | |
| <div class="row"> | |
| <!-- Sidebar Column --> | |
| <div class="col-md-3" id="tg-sb-sidebar"> | |
| <ul id="mysidebar" class="nav"> | |
| <li class="sidebarTitle"> | |
| <label for="docVersion">Eclipse Ditto™ version:</label> | |
| <div class="select-wrapper"> | |
| <select id="docVersion" name="docVersion"> | |
| <option value="">development</option> | |
| <option value="2.0">2.0</option> | |
| <option value="1.5">1.5</option> | |
| <option value="1.4">1.4</option> | |
| <option value="1.3">1.3</option> | |
| <option value="1.2">1.2</option> | |
| <option value="1.1">1.1</option> | |
| <option value="1.0">1.0</option> | |
| </select> | |
| </div> | |
| <div id="dev-warning"> | |
| <div markdown="span" class="alert alert-warning" role="alert" style="font-size:0.6em"><i class="fa fa-warning"></i> <b>Important:</b> This documentation reflects the latest 'development'. You might want to choose a released version.</div> | |
| </div> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Introduction</a> | |
| <ul> | |
| <li><a href="intro-overview.html">Overview</a></li> | |
| <li><a href="intro-digitaltwins.html">Digital twins</a></li> | |
| <li><a href="intro-hello-world.html">Hello world</a></li> | |
| </ul> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Release Notes</a> | |
| <ul> | |
| <li><a href="release_notes_201.html">2.0.1</a></li> | |
| <li><a href="release_notes_200.html">2.0.0</a></li> | |
| <li><a href="release_notes_151.html">1.5.1</a></li> | |
| <li><a href="release_notes_150.html">1.5.0</a></li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Archive</a> | |
| <ul> | |
| <li><a href="release_notes_140.html">1.4.0</a></li> | |
| <li><a href="release_notes_130.html">1.3.0</a></li> | |
| <li><a href="release_notes_121.html">1.2.1</a></li> | |
| <li><a href="release_notes_120.html">1.2.0</a></li> | |
| <li><a href="release_notes_115.html">1.1.5</a></li> | |
| <li><a href="release_notes_113.html">1.1.3</a></li> | |
| <li><a href="release_notes_112.html">1.1.2</a></li> | |
| <li><a href="release_notes_111.html">1.1.1</a></li> | |
| <li><a href="release_notes_110.html">1.1.0</a></li> | |
| <li><a href="release_notes_100.html">1.0.0</a></li> | |
| <li><a href="release_notes_090.html">0.9.0</a></li> | |
| <li><a href="release_notes_080.html">0.8.0</a></li> | |
| <li><a href="release_notes_100-M2.html">1.0.0-M2</a></li> | |
| <li><a href="release_notes_100-M1a.html">1.0.0-M1a</a></li> | |
| <li><a href="release_notes_090-M2.html">0.9.0-M2</a></li> | |
| <li><a href="release_notes_090-M1.html">0.9.0-M1</a></li> | |
| <li><a href="release_notes_080-M3.html">0.8.0-M3</a></li> | |
| <li><a href="release_notes_080-M2.html">0.8.0-M2</a></li> | |
| <li><a href="release_notes_080-M1.html">0.8.0-M1</a></li> | |
| <li><a href="release_notes_030-M2.html">0.3.0-M2</a></li> | |
| <li><a href="release_notes_030-M1.html">0.3.0-M1</a></li> | |
| <li><a href="release_notes_020-M1.html">0.2.0-M1</a></li> | |
| <li><a href="release_notes_010-M3.html">0.1.0-M3</a></li> | |
| <li><a href="release_notes_010-M1.html">0.1.0-M1</a></li> | |
| </ul> | |
| </li> | |
| </ul> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Installation</a> | |
| <ul> | |
| <li><a href="installation-building.html">Building Ditto</a></li> | |
| <li><a href="installation-running.html">Running Ditto</a></li> | |
| <li><a href="installation-operating.html">Operating Ditto</a></li> | |
| </ul> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Basic concepts</a> | |
| <ul> | |
| <li><a href="basic-overview.html">Overview</a></li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Model entities</a> | |
| <ul> | |
| <li><a href="basic-thing.html">Thing</a></li> | |
| <li><a href="basic-feature.html">Feature</a></li> | |
| <li><a href="basic-policy.html">Policy</a></li> | |
| <li><a href="basic-namespaces-and-names.html">Namespaces and Names</a></li> | |
| <li><a href="basic-metadata.html">Thing Metadata</a></li> | |
| <li><a href="basic-errors.html">Errors</a></li> | |
| </ul> | |
| </li> | |
| <li><a href="basic-auth.html">Authentication and Authorization</a></li> | |
| <li><a href="basic-messages.html">Messages</a></li> | |
| <li><a href="basic-signals.html">Signals</a></li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Signal types</a> | |
| <ul> | |
| <li><a href="basic-signals-command.html">Command</a></li> | |
| <li><a href="basic-signals-commandresponse.html">Command response</a></li> | |
| <li><a href="basic-signals-errorresponse.html">Error response</a></li> | |
| <li><a href="basic-signals-event.html">Event</a></li> | |
| <li><a href="basic-signals-announcement.html">Announcement</a></li> | |
| </ul> | |
| </li> | |
| <li><a href="basic-apis.html">APIs</a></li> | |
| <li><a href="basic-connections.html">Connections</a></li> | |
| <li><a href="basic-placeholders.html">Placeholders</a></li> | |
| <li><a href="basic-changenotifications.html">Change notifications</a></li> | |
| <li><a href="basic-rql.html">RQL expressions</a></li> | |
| <li><a href="basic-enrichment.html">Signal enrichment</a></li> | |
| <li><a href="basic-search.html">Search</a></li> | |
| <li><a href="basic-acknowledgements.html">Acknowledgements / QoS</a></li> | |
| </ul> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Advanced concepts</a> | |
| <ul> | |
| <li><a href="advanced-data-by-pass.html">Data By-Pass</a></li> | |
| </ul> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Architecture</a> | |
| <ul> | |
| <li><a href="architecture-overview.html">Overview</a></li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Services</a> | |
| <ul> | |
| <li><a href="architecture-services-policies.html">Policies</a></li> | |
| <li><a href="architecture-services-things.html">Things</a></li> | |
| <li><a href="architecture-services-things-search.html">Things-Search</a></li> | |
| <li><a href="architecture-services-connectivity.html">Connectivity</a></li> | |
| <li><a href="architecture-services-concierge.html">Concierge</a></li> | |
| <li><a href="architecture-services-gateway.html">Gateway</a></li> | |
| </ul> | |
| </li> | |
| </ul> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>HTTP API</a> | |
| <ul> | |
| <li><a href="httpapi-overview.html">Overview</a></li> | |
| <li class="active"><a href="httpapi-concepts.html">Concepts</a></li> | |
| <li><a href="httpapi-search.html">Search</a></li> | |
| <li><a href="httpapi-messages.html">Messages</a></li> | |
| <li><a href="httpapi-protocol-bindings-websocket.html">WebSocket protocol binding</a></li> | |
| <li><a href="httpapi-protocol-bindings-cloudevents.html">Cloud Events HTTP protocol binding</a></li> | |
| <li><a href="httpapi-sse.html">Server sent events</a></li> | |
| </ul> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Connectivity API</a> | |
| <ul> | |
| <li><a href="connectivity-overview.html">Overview</a></li> | |
| <li><a href="connectivity-manage-connections.html">Manage connections</a></li> | |
| <li><a href="connectivity-protocol-bindings-amqp091.html">AMQP 0.9.1 protocol binding</a></li> | |
| <li><a href="connectivity-protocol-bindings-amqp10.html">AMQP 1.0 protocol binding</a></li> | |
| <li><a href="connectivity-protocol-bindings-mqtt.html">MQTT 3.1.1 protocol binding</a></li> | |
| <li><a href="connectivity-protocol-bindings-mqtt5.html">MQTT 5 protocol binding</a></li> | |
| <li><a href="connectivity-protocol-bindings-http.html">HTTP 1.1 protocol binding</a></li> | |
| <li><a href="connectivity-protocol-bindings-kafka2.html">Kafka 2.x protocol binding</a></li> | |
| <li><a href="connectivity-mapping.html">Payload mapping</a></li> | |
| <li><a href="connectivity-header-mapping.html">Header mapping</a></li> | |
| <li><a href="connectivity-tls-certificates.html">TLS certificates</a></li> | |
| <li><a href="connectivity-ssh-tunneling.html">SSH tunneling</a></li> | |
| </ul> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Client SDK</a> | |
| <ul> | |
| <li><a href="client-sdk-overview.html">Overview</a></li> | |
| <li><a href="client-sdk-java.html">Java</a></li> | |
| <li><a href="client-sdk-javascript.html">JavaScript</a></li> | |
| </ul> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>Ditto Protocol</a> | |
| <ul> | |
| <li><a href="protocol-overview.html">Overview</a></li> | |
| <li><a href="protocol-twinlive.html">Twin/live channel</a></li> | |
| <li><a href="protocol-specification.html">Specification</a></li> | |
| <li><a href="protocol-specification-topic.html">Protocol topic</a></li> | |
| <li><a href="protocol-specification-errors.html">Errors</a></li> | |
| <li><a href="protocol-specification-things.html">Things group</a></li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>→ commands/events</a> | |
| <ul> | |
| <li><a href="protocol-specification-things-create-or-modify.html">Create/Modify</a></li> | |
| <li><a href="protocol-specification-things-merge.html">Merge</a></li> | |
| <li><a href="protocol-specification-things-retrieve.html">Retrieve</a></li> | |
| <li><a href="protocol-specification-things-delete.html">Delete</a></li> | |
| <li><a href="protocol-specification-acks.html">Acknowledgements</a></li> | |
| </ul> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>→ search/messages</a> | |
| <ul> | |
| <li><a href="protocol-specification-things-search.html">Search</a></li> | |
| <li><a href="protocol-specification-things-messages.html">Messages</a></li> | |
| </ul> | |
| </li> | |
| <li><a href="protocol-specification-policies.html">Policies group</a></li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>→ commands/events</a> | |
| <ul> | |
| <li><a href="protocol-specification-policies-create-or-modify.html">Create/Modify</a></li> | |
| <li><a href="protocol-specification-policies-retrieve.html">Retrieve</a></li> | |
| <li><a href="protocol-specification-policies-delete.html">Delete</a></li> | |
| <li><a href="protocol-specification-policies-announcement.html">Announcement</a></li> | |
| </ul> | |
| </li> | |
| <li><a href="protocol-bindings.html">Bindings</a></li> | |
| <li><a href="protocol-examples.html">Examples</a></li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>→ Things examples</a> | |
| <ul> | |
| <li><a href="protocol-examples-creatething.html">Create a Thing</a></li> | |
| <li><a href="protocol-examples-deletething.html">Delete a Thing</a></li> | |
| <li><a href="protocol-examples-modifything.html">Modify a Thing</a></li> | |
| <li><a href="protocol-examples-retrievething.html">Retrieve a Thing</a></li> | |
| <li><a href="protocol-examples-retrievethings.html">Retrieve multiple Things</a></li> | |
| <li><a href="protocol-examples-modifypolicyid.html">Modify the Policy ID of a Thing</a></li> | |
| <li><a href="protocol-examples-createattributes.html">Create Attributes</a></li> | |
| <li><a href="protocol-examples-deleteattributes.html">Delete Attributes</a></li> | |
| <li><a href="protocol-examples-modifyattributes.html">Modify Attributes</a></li> | |
| <li><a href="protocol-examples-retrieveattributes.html">Retrieve Attributes</a></li> | |
| <li><a href="protocol-examples-createattribute.html">Create a single Attribute</a></li> | |
| <li><a href="protocol-examples-deleteattribute.html">Delete a single Attribute</a></li> | |
| <li><a href="protocol-examples-modifyattribute.html">Modify a single Attribute</a></li> | |
| <li><a href="protocol-examples-retrieveattribute.html">Retrieve a single Attribute</a></li> | |
| <li><a href="protocol-examples-createthingdefinition.html">Create a Definition</a></li> | |
| <li><a href="protocol-examples-deletethingdefinition.html">Delete a Definition</a></li> | |
| <li><a href="protocol-examples-modifythingdefinition.html">Modify a Definition</a></li> | |
| <li><a href="protocol-examples-retrievethingdefinition.html">Retrieve a Definition</a></li> | |
| <li><a href="protocol-examples-createfeatures.html">Create Features</a></li> | |
| <li><a href="protocol-examples-deletefeatures.html">Delete Features</a></li> | |
| <li><a href="protocol-examples-modifyfeatures.html">Modify Features</a></li> | |
| <li><a href="protocol-examples-retrievefeatures.html">Retrieve Features</a></li> | |
| <li><a href="protocol-examples-createfeature.html">Create a single Feature</a></li> | |
| <li><a href="protocol-examples-deletefeature.html">Delete a single Feature</a></li> | |
| <li><a href="protocol-examples-modifyfeature.html">Modify a single Feature</a></li> | |
| <li><a href="protocol-examples-retrievefeature.html">Retrieve a single Feature</a></li> | |
| <li><a href="protocol-examples-createdefinition.html">Create Feature Definition</a></li> | |
| <li><a href="protocol-examples-deletedefinition.html">Delete Feature Definition</a></li> | |
| <li><a href="protocol-examples-modifydefinition.html">Modify Feature Definition</a></li> | |
| <li><a href="protocol-examples-retrievedefinition.html">Retrieve Feature Definition</a></li> | |
| <li><a href="protocol-examples-createproperties.html">Create Feature Properties</a></li> | |
| <li><a href="protocol-examples-deleteproperties.html">Delete Feature Properties</a></li> | |
| <li><a href="protocol-examples-modifyproperties.html">Modify Feature Properties</a></li> | |
| <li><a href="protocol-examples-retrieveproperties.html">Retrieve Feature Properties</a></li> | |
| <li><a href="protocol-examples-createproperty.html">Create a single Property</a></li> | |
| <li><a href="protocol-examples-deleteproperty.html">Delete a single Property</a></li> | |
| <li><a href="protocol-examples-modifyproperty.html">Modify a single Property</a></li> | |
| <li><a href="protocol-examples-retrieveproperty.html">Retrieve a single Property</a></li> | |
| <li><a href="protocol-examples-createdesiredproperties.html">Create desired Feature Properties</a></li> | |
| <li><a href="protocol-examples-deletedesiredproperties.html">Delete desired Feature Properties</a></li> | |
| <li><a href="protocol-examples-modifydesiredproperties.html">Modify desired Feature Properties</a></li> | |
| <li><a href="protocol-examples-retrievedesiredproperties.html">Retrieve desired Feature Properties</a></li> | |
| <li><a href="protocol-examples-createdesiredproperty.html">Create a single desired Property</a></li> | |
| <li><a href="protocol-examples-deletedesiredproperty.html">Delete a single desired Property</a></li> | |
| <li><a href="protocol-examples-modifydesiredproperty.html">Modify a single desired Property</a></li> | |
| <li><a href="protocol-examples-retrievedesiredproperty.html">Retrieve a single desired Property</a></li> | |
| <li><a href="protocol-examples-errorresponses.html">Error responses</a></li> | |
| </ul> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>→ Things merge examples</a> | |
| <ul> | |
| <li><a href="protocol-examples-mergething.html">Merge a Thing</a></li> | |
| <li><a href="protocol-examples-mergepolicyid.html">Merge the Policy ID of a Thing</a></li> | |
| <li><a href="protocol-examples-mergeattributes.html">Merge Attributes</a></li> | |
| <li><a href="protocol-examples-mergeattribute.html">Merge a single Attribute</a></li> | |
| <li><a href="protocol-examples-mergethingdefinition.html">Merge a Definition</a></li> | |
| <li><a href="protocol-examples-mergefeatures.html">Merge Features</a></li> | |
| <li><a href="protocol-examples-mergefeature.html">Merge a single Feature</a></li> | |
| <li><a href="protocol-examples-mergefeaturedefinition.html">Merge Feature Definition</a></li> | |
| <li><a href="protocol-examples-mergeproperties.html">Merge Feature Properties</a></li> | |
| <li><a href="protocol-examples-mergeproperty.html">Merge a single Property</a></li> | |
| <li><a href="protocol-examples-mergedesiredproperties.html">Merge desired Feature Properties</a></li> | |
| <li><a href="protocol-examples-mergedesiredproperty.html">Merge a single desired Property</a></li> | |
| <li><a href="protocol-examples-errorresponses.html">Error responses</a></li> | |
| </ul> | |
| </li> | |
| <li class="subfolders"> | |
| <a href="#"><span></span>→ Policies examples</a> | |
| <ul> | |
| <li><a href="protocol-examples-policies-createpolicy.html">Create a Policy</a></li> | |
| <li><a href="protocol-examples-policies-deletepolicy.html">Delete a Policy</a></li> | |
| <li><a href="protocol-examples-policies-modifypolicy.html">Modify a Policy</a></li> | |
| <li><a href="protocol-examples-policies-retrievepolicy.html">Retrieve a Policy</a></li> | |
| <li><a href="protocol-examples-policies-modifypolicyentries.html">Modify entries</a></li> | |
| <li><a href="protocol-examples-policies-retrievepolicyentries.html">Retrieve entries</a></li> | |
| <li><a href="protocol-examples-policies-createpolicyentry.html">Create a single entry</a></li> | |
| <li><a href="protocol-examples-policies-deletepolicyentry.html">Delete a single entry</a></li> | |
| <li><a href="protocol-examples-policies-modifypolicyentry.html">Modify a single entry</a></li> | |
| <li><a href="protocol-examples-policies-retrievepolicyentry.html">Retrieve a single entry</a></li> | |
| <li><a href="protocol-examples-policies-modifysubjects.html">Modify subjects</a></li> | |
| <li><a href="protocol-examples-policies-retrievesubjects.html">Retrieve subjects</a></li> | |
| <li><a href="protocol-examples-policies-createsubject.html">Create a single subject</a></li> | |
| <li><a href="protocol-examples-policies-deletesubject.html">Delete a single subject</a></li> | |
| <li><a href="protocol-examples-policies-modifysubject.html">Modify a single subject</a></li> | |
| <li><a href="protocol-examples-policies-retrievesubject.html">Retrieve a single subject</a></li> | |
| <li><a href="protocol-examples-policies-modifyresources.html">Modify resources</a></li> | |
| <li><a href="protocol-examples-policies-retrieveresources.html">Retrieve resources</a></li> | |
| <li><a href="protocol-examples-policies-createresource.html">Create a single resource</a></li> | |
| <li><a href="protocol-examples-policies-deleteresource.html">Delete a single resource</a></li> | |
| <li><a href="protocol-examples-policies-modifyresource.html">Modify a single resource</a></li> | |
| <li><a href="protocol-examples-policies-retrieveresource.html">Retrieve a single resource</a></li> | |
| <li><a href="protocol-examples-policies-errorresponses.html">Error responses</a></li> | |
| <li><a href="protocol-examples-policies-announcement-subjectDeletion.html">Announcement for subject deletion</a></li> | |
| </ul> | |
| </li> | |
| <li><a href="protocol-examples-search.html">→ Search examples</a></li> | |
| </ul> | |
| </li> | |
| <li><a href="sandbox.html">Sandbox</a></li> | |
| <li><a href="presentations.html">Presentations</a></li> | |
| <li><a href="glossary.html">Glossary</a></li> | |
| <li><a href="feedback.html">Feedback</a></li> | |
| <p class="external"> | |
| <a href="#" id="collapseAll">Collapse All</a> | <a href="#" id="expandAll">Expand All</a> | |
| </p> | |
| </ul> | |
| <!-- this highlights the active parent class in the sidebar. this is critical so that the parent expands when you're viewing a page. This must appear below the sidebar code above. Otherwise, if placed inside customscripts.js, the script runs before the sidebar code runs and the class never gets inserted.--> | |
| <script>$("li.active").parents('li').toggleClass("active"); | |
| </script> | |
| </div> | |
| <!-- Content Column --> | |
| <div class="col-md-9" id="tg-sb-content"> | |
| <div class="post-header"> | |
| <h1 class="post-title-main">HTTP API concepts</h1> | |
| </div> | |
| <div class="post-content"> | |
| <!-- this handles the automatic toc. use ## for subheads to auto-generate the on-page minitoc. if you use html tags, you must supply an ID for the heading element in order for it to appear in the minitoc. --> | |
| <script> | |
| $( document ).ready(function() { | |
| // Handler for .ready() called. | |
| $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3,h4' }); | |
| /* this offset helps account for the space taken up by the floating toolbar. */ | |
| $('#toc').on('click', 'a', function() { | |
| var target = $(this.getAttribute('href')) | |
| , scroll_target = target.offset().top | |
| $(window).scrollTop(scroll_target - 10); | |
| return false | |
| }) | |
| }); | |
| </script> | |
| <div id="toc"></div> | |
| <p>Ditto’s <a href="http-api-doc.html">HTTP API</a> follows some concepts which are documented on this page.</p> | |
| <p>The entry point into the HTTP API is:</p> | |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://localhost:8080/api/<apiVersion> | |
| </code></pre></div></div> | |
| <h2 id="api-versioning">API versioning</h2> | |
| <p>Ditto’s HTTP API is versioned in the URL: <code class="highlighter-rouge">/api/<apiVersion></code>. Currently, Ditto only provides API version <code class="highlighter-rouge">2</code>.<br /> | |
| API version 1 was deprecated and deleted as of Ditto version 2.0.0</p> | |
| <p>The API version is a promise that no HTTP resources (the static ones defined by Ditto itself) are modified in an | |
| incompatible/breaking way. As the HTTP resources reflect the JSON structure of the <code class="highlighter-rouge">Thing</code> entity, that also applies | |
| for this entity.</p> | |
| <p>In API 2 the <code class="highlighter-rouge">Thing</code> structure contains a <a href="basic-policy.html">Policy</a> where the authorization information is | |
| managed.</p> | |
| <h2 id="endpoints">Endpoints</h2> | |
| <p>In the HTTP API, some endpoints are static and can be seen as the “schema” of Ditto. They are in sync with the JSON | |
| representation of the model classes, e.g. <a href="basic-thing.html#model-specification">Thing</a> for the layout of the <code class="highlighter-rouge">/things</code> | |
| endpoint and <a href="basic-policy.html">Policy</a> for the layout of the <code class="highlighter-rouge">/policies</code> endpoint.</p> | |
| <h3 id="api-version-2">API version 2</h3> | |
| <p>In API version 2, a <code class="highlighter-rouge">Thing</code> contains a <code class="highlighter-rouge">policyId</code>, which points to a <code class="highlighter-rouge">Policy</code> managed as another entity. | |
| Its API endpoint is <code class="highlighter-rouge">/policies</code>.</p> | |
| <h4 id="things-in-api-2"><code class="highlighter-rouge">/things</code> in API 2</h4> | |
| <p>The base endpoint for accessing and working with <code class="highlighter-rouge">Things</code>.<br /> | |
| A <code class="highlighter-rouge">Thing</code> in API 2 has the following JSON structure:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"thingId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{thingId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"policyId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{policyId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{definition}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"features"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p>This maps to the following HTTP API endpoints:</p> | |
| <ul> | |
| <li><code class="highlighter-rouge">/things/{thingId}</code>: accessing a complete specific thing</li> | |
| <li><code class="highlighter-rouge">/things/{thingId}/policyId</code>: accessing the policy ID of the specific thing</li> | |
| <li><code class="highlighter-rouge">/things/{thingId}/definition</code>: accessing the definition of the specific thing</li> | |
| <li><code class="highlighter-rouge">/things/{thingId}/attributes</code>: accessing the attributes of the specific thing</li> | |
| <li><code class="highlighter-rouge">/things/{thingId}/features</code>: accessing the features of the specific thing</li> | |
| </ul> | |
| <h4 id="things-in-api-2---dynamic-part"><code class="highlighter-rouge">/things</code> in API 2 - dynamic part</h4> | |
| <p>Additionally to that “static part” of the HTTP API which is defined by Ditto, the API is dynamically enhanced by the | |
| JSON structure of the Thing.<br /></p> | |
| <div class="alert alert-info" role="alert"><i class="fa fa-info-circle"></i> <b>Note:</b> This automatically turns each small aspect of a <strong>digital twin</strong> into an API endpoint.</div> | |
| <p>For example for a <code class="highlighter-rouge">Thing</code> with following content:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"thingId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{thingId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"policyId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{policyId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{definition}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"manufacturer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ACME corp"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"complex"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"some"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"serialNo"</span><span class="p">:</span><span class="w"> </span><span class="mi">4711</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"features"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"lamp"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"on"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"color"</span><span class="p">:</span><span class="w"> </span><span class="s2">"blue"</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p>The following additional API endpoints are automatically available:</p> | |
| <ul> | |
| <li><code class="highlighter-rouge">/things/{thingId}/attributes/manufacturer</code>: accessing the attribute <code class="highlighter-rouge">manufacturer</code> of the specific thing</li> | |
| <li><code class="highlighter-rouge">/things/{thingId}/attributes/complex</code>: accessing the attribute <code class="highlighter-rouge">complex</code> of the specific thing</li> | |
| <li><code class="highlighter-rouge">/things/{thingId}/attributes/complex/some</code>: accessing the attribute <code class="highlighter-rouge">complex/some</code> of the specific thing</li> | |
| <li><code class="highlighter-rouge">/things/{thingId}/attributes/complex/serialNo</code>: accessing the attribute <code class="highlighter-rouge">complex/serialNo</code> of the specific thing</li> | |
| <li><code class="highlighter-rouge">/things/{thingId}/features/lamp</code>: accessing the feature <code class="highlighter-rouge">lamp</code> of the specific thing</li> | |
| <li><code class="highlighter-rouge">/things/{thingId}/features/lamp/properties</code>: accessing all properties of the feature <code class="highlighter-rouge">lamp</code> of the specific thing</li> | |
| <li><code class="highlighter-rouge">/things/{thingId}/features/lamp/properties/on</code>: accessing the <code class="highlighter-rouge">on</code> property of the feature <code class="highlighter-rouge">lamp</code> of the specific | |
| thing</li> | |
| <li><code class="highlighter-rouge">/things/{thingId}/features/lamp/properties/color</code>: accessing the <code class="highlighter-rouge">color</code> properties of the feature <code class="highlighter-rouge">lamp</code> of the | |
| specific thing</li> | |
| </ul> | |
| <h4 id="policies-in-api-2"><code class="highlighter-rouge">/policies</code> in API 2</h4> | |
| <p>The base endpoint for accessing and working with <code class="highlighter-rouge">Policies</code>.<br /> | |
| A <code class="highlighter-rouge">Policy</code> in API 2 has the following JSON structure:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"policyId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{policyId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"entries"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"{entryLabel-1}"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"subjects"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"{subjectId1}"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"resources"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"{resource1}"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p>This maps to the following HTTP API endpoints:</p> | |
| <ul> | |
| <li><code class="highlighter-rouge">/policies/{policyId}</code>: accessing complete <code class="highlighter-rouge">Policy</code></li> | |
| <li><code class="highlighter-rouge">/policies/{policyId}/entries</code>: accessing the <code class="highlighter-rouge">Policy</code> entries</li> | |
| <li><code class="highlighter-rouge">/policies/{policyId}/entries/{entryLabel-1}</code>: accessing a single <code class="highlighter-rouge">Policy</code> entry with the label <code class="highlighter-rouge">{entryLabel-1}</code></li> | |
| <li><code class="highlighter-rouge">/policies/{policyId}/entries/{entryLabel-1}/subjects</code>: accessing the subjects of a single <code class="highlighter-rouge">Policy</code> entry with the | |
| label <code class="highlighter-rouge">{entryLabel-1}</code></li> | |
| <li><code class="highlighter-rouge">/policies/{policyId}/entries/{entryLabel-1}/resources</code>: accessing the resources of a single <code class="highlighter-rouge">Policy</code> entry with the | |
| label <code class="highlighter-rouge">{entryLabel-1}</code></li> | |
| </ul> | |
| <h2 id="partial-updates">Partial updates</h2> | |
| <p>As a benefit of the above mentioned mechanism that an API is automatically available based on the JSON structure, the | |
| “partial update” pattern can be applied when modifying data.</p> | |
| <p>The benefit of this is a reduction in payload to be transferred. Further, it is beneficial because other parts of the | |
| <code class="highlighter-rouge">Thing</code> are not overwritten with a potentially outdated value - only the actually changed data part can be modified.</p> | |
| <p>So instead of modifying a complete <code class="highlighter-rouge">Thing</code> only a specific part is affected.</p> | |
| <p>Given, the <code class="highlighter-rouge">on</code> property of <code class="highlighter-rouge">lamp</code> should be changed to <code class="highlighter-rouge">true</code>.</p> | |
| <p>Instead of<br /> | |
| <br /> | |
| <code class="highlighter-rouge">PUT .../things/{thingId}</code> with the complete payload:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"thingId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{thingId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"policyId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{policyId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{definition}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"manufacturer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ACME corp"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"complex"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"some"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"serialNo"</span><span class="p">:</span><span class="w"> </span><span class="mi">4711</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"features"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"lamp"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"on"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"color"</span><span class="p">:</span><span class="w"> </span><span class="s2">"blue"</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p>we can use a smarter request<br /><code class="highlighter-rouge">PUT .../things/{thingId}/features/lamp/properties/on</code> with a minimal payload:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kc">true</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <h2 id="partial-requests">Partial requests</h2> | |
| <p>Similar to the partial updates from above, the HTTP API can also be used to retrieve a single value instead of a | |
| complete <code class="highlighter-rouge">Thing</code>.</p> | |
| <p>Again, the benefit is a reduction in response payload and that the caller can directly use the returned data value | |
| (for example expect it to be a <code class="highlighter-rouge">boolean</code> and treat it accordingly).</p> | |
| <p>For example, we can request<br /><code class="highlighter-rouge">GET .../things/{thingId}/features/lamp/properties/on</code> and get as response:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kc">true</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <h3 id="with-field-selector">With field selector</h3> | |
| <p>A further mechanism in the API for partial requests is using a so-called field selector. This is useful when the JSON | |
| structure of the <code class="highlighter-rouge">Thing</code> or other entity should be kept intact, but not all information is relevant.</p> | |
| <p>The field selector is passed as a HTTP query parameter <code class="highlighter-rouge">fields</code> and contains a comma separated list of fields to include | |
| in the response.</p> | |
| <p>Given, you have the following Thing:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"thingId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{thingId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"policyId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{policyId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{definition}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"manufacturer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ACME corp"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"complex"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"some"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"serialNo"</span><span class="p">:</span><span class="w"> </span><span class="mi">4711</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"misc"</span><span class="p">:</span><span class="w"> </span><span class="s2">"foo"</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"features"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"lamp"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"on"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"color"</span><span class="p">:</span><span class="w"> </span><span class="s2">"blue"</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <h4 id="field-selector-examples">Field selector examples</h4> | |
| <p>The following <code class="highlighter-rouge">GET</code> request examples with field selectors show how you can retrieve only the parts of a thing which you | |
| are interested in:</p> | |
| <p><code class="highlighter-rouge">GET .../things/{thingId}?fields=attributes</code><br /> | |
| Response:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"manufacturer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ACME corp"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"complex"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"some"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"serialNo"</span><span class="p">:</span><span class="w"> </span><span class="mi">4711</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"misc"</span><span class="p">:</span><span class="w"> </span><span class="s2">"foo"</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p><code class="highlighter-rouge">GET .../things/{thingId}?fields=attributes/manufacturer</code><br /> | |
| Response:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"manufacturer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ACME corp"</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p><code class="highlighter-rouge">GET .../things/{thingId}?fields=attributes/complex/serialNo</code><br /> | |
| Response:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"complex"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"serialNo"</span><span class="p">:</span><span class="w"> </span><span class="mi">4711</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p><code class="highlighter-rouge">GET .../things/{thingId}?fields=attributes/complex/some,attributes/complex/serialNo</code><br /> | |
| Response:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"complex"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"some"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"serialNo"</span><span class="p">:</span><span class="w"> </span><span class="mi">4711</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p><code class="highlighter-rouge">GET .../things/{thingId}?fields=attributes/complex(some,serialNo)</code><br /> | |
| Response:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"complex"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"some"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"serialNo"</span><span class="p">:</span><span class="w"> </span><span class="mi">4711</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p><code class="highlighter-rouge">GET .../things/{thingId}?fields=attributes/complex/misc,features/lamp/properties/on</code><br /> | |
| Response:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"complex"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"misc"</span><span class="p">:</span><span class="w"> </span><span class="s2">"foo"</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"features"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"lamp"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"on"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <h2 id="merge-updates">Merge updates</h2> | |
| <p>Merge updates can be used to update multiple parts of a Thing <em>in a single request</em> e.g. multiple properties of | |
| different features or a feature property and an attribute value. Merge updates are applied by using the HTTP | |
| <code class="highlighter-rouge">PATCH</code> method with the payload in <a href="https://tools.ietf.org/html/rfc7396">JSON merge patch (RFC-7396)</a> format. The | |
| content-type of the request must be set to <code class="highlighter-rouge">application/merge-patch+json</code>.</p> | |
| <p><a href="https://tools.ietf.org/html/rfc7396">RFC-7396</a> specifies how a set of modifications is applied to an existing JSON | |
| document:</p> | |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A JSON merge patch document describes changes to be made to a target JSON document using a syntax that closely | |
| mimics the document being modified. Recipients of a merge patch document determine the exact set of changes being | |
| requested by comparing the content of the provided patch against the current content of the target document. | |
| If the provided merge patch contains members that do not appear within the target, those members are added. If the | |
| target does contain the member, the value is replaced. Null values in the merge patch are given special meaning to | |
| indicate the removal of existing values in the target. | |
| </code></pre></div></div> | |
| <div class="alert alert-info" role="alert"><i class="fa fa-info-circle"></i> <b>Note:</b> Please note the special meaning of <code class="highlighter-rouge">null</code> values. When using <code class="highlighter-rouge">PATCH</code> a <code class="highlighter-rouge">null</code> value is | |
| interpreted as delete in contrast to <code class="highlighter-rouge">PUT</code> requests where <code class="highlighter-rouge">null</code> values have no special meaning. </div> | |
| <p>Like <code class="highlighter-rouge">PUT</code> requests, <code class="highlighter-rouge">PATCH</code> requests can be applied at any level of the JSON structure of a thing, e.g. patching a | |
| complete thing at root level or patching a single property value at property level.</p> | |
| <h3 id="permissions-required-for-merge-update">Permissions required for merge update</h3> | |
| <p>To successfully execute merge update the authorized subject needs to have <em>WRITE</em> permission on <em>all</em> resources | |
| affected by the provided JSON merge patch. If the permission is missing for one of the affected resources the whole | |
| merge patch is <em>rejected</em>, i.e. the merge update is executed as a whole or not at all.</p> | |
| <h3 id="merge-update-example">Merge update example</h3> | |
| <p>Given an existing thing with the JSON structure:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"thingId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{thingId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"policyId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{policyId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"location"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"longitude"</span><span class="p">:</span><span class="w"> </span><span class="mf">47.682170</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"latitude"</span><span class="p">:</span><span class="w"> </span><span class="mf">9.386372</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"serialNo"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0000000"</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"features"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"temperature"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mf">25.43</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"unit"</span><span class="p">:</span><span class="w"> </span><span class="s2">"°C"</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"pressure"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mf">1013.25</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"unit"</span><span class="p">:</span><span class="w"> </span><span class="s2">"hPa"</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p>Assuming a single request should:</p> | |
| <ul> | |
| <li>add the <code class="highlighter-rouge">manufacturer</code> attribute</li> | |
| <li>update the existing <code class="highlighter-rouge">serialNo</code> attribute to the value of <code class="highlighter-rouge">23091861</code></li> | |
| <li>remove the existing <code class="highlighter-rouge">location</code> attribute</li> | |
| <li>set the existing property <code class="highlighter-rouge">value</code> of feature <code class="highlighter-rouge">temperature</code> to the value of <code class="highlighter-rouge">26.89</code></li> | |
| <li>remove the existing property <code class="highlighter-rouge">unit</code> of feature <code class="highlighter-rouge">pressure</code></li> | |
| <li>add a new feature <code class="highlighter-rouge">humidity</code></li> | |
| </ul> | |
| <p>This can be achieved using a <code class="highlighter-rouge">PATCH .../things/{thingId}</code> with the request payload of</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"location"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"manufacturer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Bosch"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"serialNo"</span><span class="p">:</span><span class="w"> </span><span class="s2">"23091861"</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"features"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"temperature"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mf">26.89</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"pressure"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"unit"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"humidity"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">55</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"unit"</span><span class="p">:</span><span class="w"> </span><span class="s2">"%"</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p>The resulting JSON representation of the updated thing after applying the <code class="highlighter-rouge">PATCH</code> is:</p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"thingId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{thingId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"policyId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{policyId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"manufacturer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Bosch"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"serialNo"</span><span class="p">:</span><span class="w"> </span><span class="s2">"23091861"</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"features"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"temperature"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mf">26.89</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"unit"</span><span class="p">:</span><span class="w"> </span><span class="s2">"°C"</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"pressure"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">1015</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">},</span><span class="w"> | |
| </span><span class="s2">"humidity"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">55</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"unit"</span><span class="p">:</span><span class="w"> </span><span class="s2">"%"</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <h2 id="conditional-requests">Conditional Requests</h2> | |
| <p>The HTTP API for <code class="highlighter-rouge">Things</code> and <code class="highlighter-rouge">Policies</code> partially supports <code class="highlighter-rouge">Conditional Requests</code> as defined | |
| in <a href="https://tools.ietf.org/html/rfc7232">RFC-7232</a>.</p> | |
| <h3 id="etag">ETag</h3> | |
| <p>A successful response on a <code class="highlighter-rouge">thing</code> or <code class="highlighter-rouge">policy</code> resource provides an <code class="highlighter-rouge">ETag</code> header.</p> | |
| <ul> | |
| <li>For read responses, it contains the current entity-tag of the resource.</li> | |
| <li>For write responses, it contains the entity-tag after successful write.</li> | |
| </ul> | |
| <p>The <code class="highlighter-rouge">ETag</code> has a different format for top-level resources and sub-resources.</p> | |
| <ul> | |
| <li>Top-level resources (e.g. <code class="highlighter-rouge">.../things/{thingId}</code>): The entity-tag contains the revision of the entity which is | |
| addressed by the resource in the format <code class="highlighter-rouge">"rev:<revision>"</code>, e.g. <code class="highlighter-rouge">"rev:2"</code>.</li> | |
| <li>Sub-resources (e.g. <code class="highlighter-rouge">.../things/{thingId}/features/{featureId}</code>): The entity-tag contains a hash of the current value | |
| of the addressed sub-resource in the format <code class="highlighter-rouge">"hash:<calculated-hash>"</code>, e.g. | |
| <code class="highlighter-rouge">"hash:87192253740"</code>. Note that this format may change in the future.</li> | |
| </ul> | |
| <h3 id="conditional-headers">Conditional Headers</h3> | |
| <p>The following request headers can be used to issue a conditional request:</p> | |
| <ul> | |
| <li><code class="highlighter-rouge">If-Match</code>: | |
| <ul> | |
| <li>Read or write the resource only | |
| <ul> | |
| <li>if the current entity-tag matches at least one of the entity-tags provided in this header</li> | |
| <li>or if the header is <code class="highlighter-rouge">*</code> and the entity exists</li> | |
| </ul> | |
| </li> | |
| <li>The response will be: | |
| <ul> | |
| <li>in case of a match, the same response as if the header wouldn’t have been specified</li> | |
| <li>in case of no match, status <code class="highlighter-rouge">412 (Precondition Failed)</code> with an error response containing detail information | |
| and the current entity-tag of the resource as <code class="highlighter-rouge">ETag</code> header</li> | |
| </ul> | |
| </li> | |
| </ul> | |
| </li> | |
| <li><code class="highlighter-rouge">If-None-Match</code>: | |
| <ul> | |
| <li>Read or write the resource only | |
| <ul> | |
| <li>if the current entity-tag does not match any one of the entity-tags provided in this header</li> | |
| <li>or if the header is <code class="highlighter-rouge">*</code> and the entity does not exist</li> | |
| </ul> | |
| </li> | |
| <li>The response will be: | |
| <ul> | |
| <li>in case of no match, the same response as if the header wouldn’t have been specified</li> | |
| <li>in case of a match: | |
| <ul> | |
| <li>for write requests, status <code class="highlighter-rouge">412 (Precondition Failed)</code> with an error response containing detail | |
| information and the current entity-tag of the resource as <code class="highlighter-rouge">ETag</code> header</li> | |
| <li>for read requests, status <code class="highlighter-rouge">304 (Not Modified)</code> without response body, with the current entity-tag of the | |
| resource as <code class="highlighter-rouge">ETag</code> header</li> | |
| </ul> | |
| </li> | |
| </ul> | |
| </li> | |
| </ul> | |
| </li> | |
| </ul> | |
| <p>Note that the Ditto HTTP API always provides a <code class="highlighter-rouge">strong</code> entity-tag in the <code class="highlighter-rouge">ETag</code> header, thus you will never receive a | |
| <code class="highlighter-rouge">weak</code> entity-tag (see <a href="https://tools.ietf.org/html/rfc7232#section-2.1">RFC-7232 Section 2.1</a>). If you convert this | |
| strong entity-tag to a weak entity-tag and use it in a Conditional Header, Ditto will handle it according to RFC-7232. | |
| However, we discourage the usage of weak entity-tags, because in the context of Ditto they only add unnecessary | |
| complexity.</p> | |
| <h3 id="exempted-fields">Exempted fields</h3> | |
| <p>Assuming you have a thing with an associated policy. When querying the thing with</p> | |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>GET .../things/{thingId}?fields=_policy | |
| </code></pre></div></div> | |
| <p>you will get the thing containing its revision and associated policy.</p> | |
| <p>If you now modify the associated policy, the revision of the thing will not change! This could lead to an inconsistent | |
| state if the thing is getting refetched by using the <code class="highlighter-rouge">If-None-Match</code> header, because this would return | |
| a <code class="highlighter-rouge">304 Not Modified</code>, even if the policy has changed.</p> | |
| <p>To tackle this, Ditto has the following list of exempted fields which automatically bypass the precondition header | |
| check:</p> | |
| <ul> | |
| <li><code class="highlighter-rouge">_policy</code></li> | |
| </ul> | |
| <h3 id="examples">Examples</h3> | |
| <p>The following examples show several scenarios on a top-level (Thing) resource. Nevertheless, these scenarios can also be | |
| applied on any sub-resource in the same way.</p> | |
| <h4 id="create-write-only-if-the-resource-does-not-exist">Create: Write only if the resource does not exist</h4> | |
| <p>The following example request shows, how you can make sure that a <code class="highlighter-rouge">PUT</code> request does not overwrite existing data, i.e. | |
| how you can enforce that the Thing can only be created by the request.</p> | |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PUT .../things/{thingId} | |
| If-None-Match: * | |
| </code></pre></div></div> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"policyId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{policyId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"manufacturer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ACME crop"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"otherData"</span><span class="p">:</span><span class="w"> </span><span class="mi">4711</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p>You will get one of the following responses:</p> | |
| <ul> | |
| <li><code class="highlighter-rouge">201 (Created)</code> in case the creation was successful, i.e. the Thing did not yet exist.</li> | |
| <li><code class="highlighter-rouge">412 (Precondition Failed)</code> in case the creation failed, i.e. a Thing with the exactly same <code class="highlighter-rouge">{thingId}</code> already | |
| exists.</li> | |
| </ul> | |
| <h4 id="update-write-only-if-the-resource-already-exists">Update: Write only if the resource already exists</h4> | |
| <p>The following example request shows how you can make sure that a <code class="highlighter-rouge">PUT</code> request does not create the resource, i.e. how | |
| you can enforce that the Thing can only be updated by the request, but you do not generate a duplicate by mistake.</p> | |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PUT .../things/{thingId} | |
| If-Match: * | |
| </code></pre></div></div> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"manufacturer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ACME crop"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"otherData"</span><span class="p">:</span><span class="w"> </span><span class="mi">4711</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p>You will get one of the following responses:</p> | |
| <ul> | |
| <li><code class="highlighter-rouge">204 (No Content)</code> in case the update was successful, i.e. the Thing already existed.</li> | |
| <li><code class="highlighter-rouge">412 (Precondition Failed)</code> in case the update failed, i.e. the Thing does not yet exist.</li> | |
| </ul> | |
| <h4 id="optimistic-locking">Optimistic Locking</h4> | |
| <p>First, <code class="highlighter-rouge">GET</code> the Thing in order to retrieve both: the current data and the entity-tag:</p> | |
| <p><code class="highlighter-rouge">GET .../things/{thingId}</code>:</p> | |
| <p>Response:</p> | |
| <p><code class="highlighter-rouge">ETag: "rev:2"</code></p> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"thingId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{thingId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"policyId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{policyId}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{definition}"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"manufacturer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ACME crop"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"otherData"</span><span class="p">:</span><span class="w"> </span><span class="mi">4711</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p>Assume that you have detected the typo in the manufacturer attribute (“ACME crop”) and want to fix this with a top-level | |
| Thing PUT. You want to make sure, that no one else has modified the Thing in the meantime, because otherwise his changes | |
| would be lost. (You could also achieve this with a PUT on the concrete attribute, but for this example we assume that | |
| you want to use a top-level Thing PUT.)</p> | |
| <p><code class="highlighter-rouge">PUT</code> the Thing with the changed data and the entity-tag from the preceding <code class="highlighter-rouge">GET</code> response in the <code class="highlighter-rouge">If-Match</code> header.</p> | |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PUT .../things/{thingId} | |
| If-Match: "rev:2" | |
| </code></pre></div></div> | |
| <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> | |
| </span><span class="s2">"manufacturer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ACME corp"</span><span class="p">,</span><span class="w"> | |
| </span><span class="s2">"otherData"</span><span class="p">:</span><span class="w"> </span><span class="mi">4711</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span><span class="p">}</span><span class="w"> | |
| </span></code></pre></div></div> | |
| <p>You will get one of the following responses:</p> | |
| <ul> | |
| <li><code class="highlighter-rouge">204 (No Content)</code> in case the update was successful, i.e. no one else has changed the Thing in the meantime.</li> | |
| <li><code class="highlighter-rouge">412 (Precondition Failed)</code> in case the update was not successful, i.e. the Thing has been changed by someone else in | |
| the meantime.</li> | |
| </ul> | |
| <div class="tags"> | |
| <b>Tags: </b> | |
| <a href="tag_http.html" class="btn btn-default navbar-btn cursorNorm" role="button">http</a> | |
| </div> | |
| </div> | |
| <hr class="shaded"/> | |
| <footer> | |
| <div class="row"> | |
| <div class="col-lg-12 footer"> | |
| <div class="logo"> | |
| <a href="https://eclipse.org"><img src="images/eclipse_foundation_logo.svg" alt="Eclipse logo"/></a> | |
| </div> | |
| <p class="notice"> | |
| ©2021 Eclipse Ditto™. | |
| Site last generated: Jul 23, 2021 <br /> | |
| </p> | |
| <div class="quickLinks"> | |
| <a href="https://www.eclipse.org/legal/privacy.php" target="_blank"> | |
| > Privacy Policy | |
| </a> | |
| <a href="https://www.eclipse.org/legal/termsofuse.php" target="_blank"> | |
| > Terms of Use | |
| </a> | |
| <a href="https://www.eclipse.org/legal/copyright.php" target="_blank"> | |
| > Copyright Agent | |
| </a> | |
| <a href="https://www.eclipse.org/legal" target="_blank"> | |
| > Legal | |
| </a> | |
| <a href="https://www.eclipse.org/legal/epl-2.0/" target="_blank"> | |
| > License | |
| </a> | |
| <a href="https://eclipse.org/security" target="_blank"> | |
| > Report a Vulnerability | |
| </a> | |
| </div> | |
| </div> | |
| </div> | |
| </footer> | |
| </div> | |
| <!-- /.row --> | |
| </div> | |
| <!-- /.container --> | |
| </div> | |
| <!-- /#main --> | |
| </div> | |
| </body> | |
| </html> |