# Three simple rules for coding with the driver

When writing code that uses the driver, there are three simple rules that you should follow that make your code
efficient:

- Only use one `Client` 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.
- If you execute a statement more than once, use a prepared statement.
- In some situations you can reduce the number of network roundtrips and also have atomic operations by using batches.

## Client 

The `Client` 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.

```javascript
const cassandra = require('cassandra-driver');
const client = new cassandra.Client({
   contactPoints: ['10.1.1.3', '10.1.1.4', '10.1.1.5'], 
   localDataCenter: 'us-east-1'
});
```

A `Client` instance is a long-lived object, your code should share the same `Client` instance across your application.

## Prepared statements 

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 are provided, 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.

Preparing and executing statements in the driver does not require two chained asynchronous calls. You can set the
`prepare` flag in the query options and the driver handles the rest.

```javascript
const query = 'SELECT id, name FROM users WHERE id = ?';
client.execute(query, [ id ], { prepare: true });
```

## Batch statements 

The batch statement combines multiple data modification statements (`INSERT`, `UPDATE`, or `DELETE`) 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 `batch()`, 
read about [atomic batches in Cassandra 1.2](http://www.datastax.com/dev/blog/atomic-batches-in-cassandra-1-2), 
[static columns and batching of conditional updates](http://www.datastax.com/dev/dev/blog/cql-in-2-0-6),
and [CQL documentation][batches]. But take into account that incorrect use of batch statements may
increase load to servers.

Batch queries should be prepared, by setting the `prepare` flag, when possible. 

```javascript
const queries = [
   { query: 'UPDATE user_profiles SET email=? WHERE key=?',
      params: [emailAddress, 'hendrix']},
   { query: 'INSERT INTO user_track (key, text, date) VALUES (?, ?, ?)',
      params: ['hendrix', 'Changed email', new Date()]}
];
const queryOptions = { prepare: true, consistency: cassandra.types.consistencies.localQuorum };

client.batch(queries, queryOptions)
  .then(() => console.log('Data updated on cluster'));
```

[batches]: https://docs.datastax.com/en/cql/3.3/cql/cql_using/useBatchTOC.html
