blob: bc1124775abadff0d4f262b361ab72423ea09e77 [file]
---
redirect_to:
- https://docs.datastax.com/en/developer/nodejs-driver/latest/coding-rules/
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<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="DataStax Nodejs Driver for Apache Cassandra">
<meta name="author" content="DataStax">
<title>DataStax Nodejs Driver, Three simple rules for coding with the driver</title>
<link rel="icon" href="../favicon.ico">
<link rel="apple-touch-icon" href="../favicon.png">
<link href="../css/style.css" rel="stylesheet">
<link href="../css/pygments.css" rel="stylesheet">
<link href="../css/hotkeys.css" rel="stylesheet">
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body ng-app="docs" data-spy="scroll" data-target="#table-of-contents" data-offset="69">
<header class="container-fluid navbar">
<div class="row">
<div class="col-sm-4">
<a class="navbar-brand" href="../"><img alt="Brand" src="../img/logo.png">DataStax Nodejs Driver</a>
</div>
<div class="col-md-4 col-md-offset-4">
<div class="row">
<div class="col-md-12">
<ul class="list-inline" role="nav">
<li><a href="https://academy.datastax.com/" class="navbar-link">DataStax Academy</a></li>
<li><a href="http://www.datastax.com/dev/blog" class="navbar-link">Tech Blog</a></li>
<li><a href="http://www.datastax.com/what-we-offer/products-services/support" class="navbar-link">Support</a></li>
</ul>
</div>
</div>
<div class="row">
<div class="col-md-8">
<form id="search" class="form-search dropdown visible-lg-block" ng-controller="search" ng-class="{open: hasResults}" role="search" ng-submit="submit()" data-spy="affix" data-offset-top="130">
<div class="form-group has-feedback">
<input type="search" class="form-control input-sm mousetrap" placeholder="Search..." ng-model="q" ng-change="search('v3.1')" ng-disabled="!searchReady" disabled data-hotkey="{down: moveDown, up: moveUp, esc: reset}" data-search>
</div>
<ul class="dropdown-menu search-results" role="menu">
<li ng-repeat="result in results" ng-class="{'bg-warning': $index == current}"><a ng-href="{{basePath}}{{result.path}}"><span ng-bind-html="summary(result)"></span></a></li>
</ul>
</form>
</div>
<div class="col-md-4">
<a href="http://www.datastax.com/download" class="btn btn-primary btn-sm">Download</a>
</div>
</div>
</div>
</div>
<div class="row crumbs-wrapper">
<div class="col-md-12">
<nav id="crumbs" data-spy="affix" data-offset-top="130">
<ol class="breadcrumb">
<li>
<div class="btn-group">
<button id="current-version" class="btn btn-default btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
v3.1
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="current-version">
<li class="disabled"><a href="./">v3.1</a></li>
<li><a href="../v3.0/coding-rules/">v3.0</a></li>
</ul>
</div>
</li>
<li><a href="../">Home</a></li>
<li class="active">Three simple rules for coding with the driver</li>
<li class="dropdown" id="table-of-contents">
<div class="btn-group">
<button id="current-section" type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">
Jump to&#8230; <span class="caret"></span><span class="sr-only">Table of Contents</span>
</button>
<ul class="dropdown-menu nav nav-pills nav-stacked">
<li><a href="#three-simple-rules-for-coding-with-the-driver">Page Top <span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span></a></li>
<li><a href="#client">Client
</a></li>
<li><a href="#prepared-statements">Prepared statements
</a></li>
<li><a href="#batch-statements">Batch statements
</a></li>
</ul>
</div>
</li>
</ol>
</nav>
</div>
</div>
</header>
<div class="container-fluid" id="content">
<div class="row">
<div class="col-md-3">
<div id="navigation" class="side-nav" role="tablist" aria-multiselectable="true">
<h3>Contents</h3>
<ul class="nav nav-pills nav-stacked">
<li>
<a href="../features/">Features <small>page</small></a>
</li>
<li>
<a href="../faq/">Frequently Asked Questions <small>page</small></a>
</li>
<li>
<a href="../getting-started/">Getting started <small>page</small></a>
</li>
<li class="active">
<a href="./" class="current">Three simple rules for coding with the driver <small>page</small></a>
</li>
</ul>
</div>
</div>
<div class="col-md-9 content">
<h1 id="three-simple-rules-for-coding-with-the-driver" class="target">Three simple rules for coding with the driver<a class="anchor" href="#three-simple-rules-for-coding-with-the-driver" aria-hidden="true"><span class="glyphicon glyphicon-link"></span></a>
</h1>
<p>When writing code that uses the driver, there are three simple rules that you should follow that make your code
efficient:</p>
<ul>
<li>Only use one <code>Client</code> instance per keyspace or use a single Client and explicitly specify the keyspace in your queries
and reuse it in across your modules in the application lifetime.</li>
<li>If you execute a statement more than once, use a prepared statement.</li>
<li>You can reduce the number of network roundtrips and also have atomic operations by using batches.</li>
</ul>
<h2 id="client" class="target">Client<a class="anchor" href="#client" aria-hidden="true"><span class="glyphicon glyphicon-link"></span></a>
</h2>
<p>The <code>Client</code> instance allows you to configure different important aspects of the way connections and queries are
handled. At this level, you can configure everything from contact points (address of the nodes to be contacted initially
before the driver performs node discovery), the request routing policy, retry and reconnection policies, and so on.
Generally such settings are set once at the application level.</p>
<pre class="highlight"><code><span class="kr">const</span> <span class="nx">cassandra</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'cassandra-driver'</span><span class="p">);</span>
<span class="kr">const</span> <span class="nx">DCAwareRoundRobinPolicy</span> <span class="o">=</span> <span class="nx">cassandra</span><span class="p">.</span><span class="nx">policies</span><span class="p">.</span><span class="nx">loadBalancing</span><span class="p">.</span><span class="nx">DCAwareRoundRobinPolicy</span><span class="p">;</span>
<span class="kr">const</span> <span class="nx">client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">cassandra</span><span class="p">.</span><span class="nx">Client</span><span class="p">({</span>
<span class="na">contactPoints</span><span class="p">:</span> <span class="p">[</span><span class="s1">'10.1.1.3'</span><span class="p">,</span> <span class="s1">'10.1.1.4'</span><span class="p">,</span> <span class="s1">'10.1.1.5'</span><span class="p">],</span>
<span class="na">policies</span><span class="p">:</span> <span class="p">{</span>
<span class="na">loadBalancing</span><span class="p">:</span> <span class="k">new</span> <span class="nx">DCAwareRoundRobinPolicy</span><span class="p">(</span><span class="s1">'US_EAST'</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</code></pre>
<p>A <code>Client</code> instance is a long-lived object, and it should not be used in a request-response, short-lived fashion.</p>
<p>Your code should share the same <code>Client</code> instance across your application.</p>
<h2 id="prepared-statements" class="target">Prepared statements<a class="anchor" href="#prepared-statements" aria-hidden="true"><span class="glyphicon glyphicon-link"></span></a>
</h2>
<p>Using prepared statements provides multiple benefits. A prepared statement is parsed and prepared on the Cassandra nodes
and is ready for future execution. When binding parameters, only they (and the query id) are sent over the wire. These
performance gains add up when using the same queries (with different parameters) repeatedly. Additionally, when
preparing, the driver retrieves information about the parameter types which allows an accurate mapping between a
JavaScript type and a CQL type.</p>
<p>Preparing and executing statements in the driver does not require two chained asynchronous calls. You can set the
<code>prepare</code> flag in the query options and the driver handles the rest.</p>
<pre class="highlight"><code><span class="kr">const</span> <span class="nx">query</span> <span class="o">=</span> <span class="s1">'SELECT id, name FROM users WHERE id = ?'</span><span class="p">;</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span><span class="nx">query</span><span class="p">,</span> <span class="p">[</span> <span class="nx">id</span> <span class="p">],</span> <span class="p">{</span> <span class="na">prepare</span><span class="p">:</span> <span class="kc">true</span> <span class="p">},</span> <span class="nx">callback</span><span class="p">);</span>
</code></pre>
<h2 id="batch-statements" class="target">Batch statements<a class="anchor" href="#batch-statements" aria-hidden="true"><span class="glyphicon glyphicon-link"></span></a>
</h2>
<p>The batch statement combines multiple data modification statements (<code>INSERT</code>, <code>UPDATE</code>, or <code>DELETE</code>) into a single logical
operation that is sent to the server in a single request. Batching together multiple operations also ensures that they
are executed in an atomic way, (that is, either all succeed or none). To make the best use of <code>batch()</code>, read about
<a href="http://www.datastax.com/dev/blog/atomic-batches-in-cassandra-1-2">atomic batches in Cassandra 1.2</a> and <a href="http://www.datastax.com/dev/dev/blog/cql-in-2-0-6">static columns
and batching of conditional updates</a>.</p>
<p>Starting with Cassandra 2.0, prepared statements can be used in batch operations.</p>
<pre class="highlight"><code><span class="kr">const</span> <span class="nx">queries</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span> <span class="na">query</span><span class="p">:</span> <span class="s1">'UPDATE user_profiles SET email=? WHERE key=?'</span><span class="p">,</span>
<span class="na">params</span><span class="p">:</span> <span class="p">[</span><span class="nx">emailAddress</span><span class="p">,</span> <span class="s1">'hendrix'</span><span class="p">]},</span>
<span class="p">{</span> <span class="na">query</span><span class="p">:</span> <span class="s1">'INSERT INTO user_track (key, text, date) VALUES (?, ?, ?)'</span><span class="p">,</span>
<span class="na">params</span><span class="p">:</span> <span class="p">[</span><span class="s1">'hendrix'</span><span class="p">,</span> <span class="s1">'Changed email'</span><span class="p">,</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">()]}</span>
<span class="p">];</span>
<span class="kr">const</span> <span class="nx">queryOptions</span> <span class="o">=</span> <span class="p">{</span> <span class="na">prepare</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="na">consistency</span><span class="p">:</span> <span class="nx">cassandra</span><span class="p">.</span><span class="nx">types</span><span class="p">.</span><span class="nx">consistencies</span><span class="p">.</span><span class="nx">quorum</span> <span class="p">};</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">batch</span><span class="p">(</span><span class="nx">queries</span><span class="p">,</span> <span class="nx">queryOptions</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">assert</span><span class="p">.</span><span class="nx">ifError</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Data updated on cluster'</span><span class="p">);</span>
<span class="p">});</span>
</code></pre>
</div>
</div>
</div>
<footer class="container text-muted">
<ul class="list-inline">
<li>
<a href="https://github.com/datastax/nodejs-driver/">Code</a>
</li>
<li>·</li>
<li>
<a href="http://datastax.github.io/nodejs-driver/">Docs</a>
</li>
<li>·</li>
<li>
<a href="https://datastax-oss.atlassian.net/projects/NODEJS/issues">Issues</a>
</li>
<li>·</li>
<li>
<a href="https://groups.google.com/a/lists.datastax.com/forum/#!forum/nodejs-driver-user">Mailing List</a>
</li>
<li>·</li>
<li>
<a href="irc://irc.freenode.net/datastax-drivers">IRC Channel</a>
</li>
<li>·</li>
<li>
<a href="https://www.npmjs.org/package/cassandra-driver">Npm</a>
</li>
</ul>
</footer>
<script src="../js/jquery.js"></script>
<script src="../js/bootstrap.js"></script>
<script src="../js/angular.js"></script>
<script src="../js/mousetrap.js"></script>
<script src="../js/hotkeys.js"></script>
<script src="../js/ZeroClipboard.js"></script>
<script src="../js/lunr.js"></script>
<script src="../js/app.js"></script>
</body>
</html>