<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Clement Delafargue, Author at Clever Cloud</title>
	<atom:link href="https://www.clever.cloud/blog/author/delafargue/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>From Code to Product</description>
	<lastBuildDate>Tue, 13 Feb 2018 09:00:00 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://cdn.clever-cloud.com/uploads/2023/03/cropped-cropped-favicon-32x32.png</url>
	<title>Clement Delafargue, Author at Clever Cloud</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Tools, not rules: why I&#8217;ve built issues-helper</title>
		<link>https://www.clever.cloud/blog/features/2018/02/13/issues-helper/</link>
		
		<dc:creator><![CDATA[Clement Delafargue]]></dc:creator>
		<pubDate>Tue, 13 Feb 2018 09:00:00 +0000</pubDate>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[play]]></category>
		<category><![CDATA[redis]]></category>
		<category><![CDATA[Scala]]></category>
		<guid isPermaLink="false">https://www2.cleverapps.io/wp/blog/technology/2018/02/13/issues-helper/</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/tools-not-rules-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="tools not rules 1" decoding="async" fetchpriority="high" srcset="https://cdn.clever-cloud.com/uploads/2021/08/tools-not-rules-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/tools-not-rules-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/tools-not-rules-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/tools-not-rules-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/tools-not-rules-1-1368x528.jpg 1368w" sizes="(max-width: 1400px) 100vw, 1400px" /></p><p>A few weeks ago I&#39;ve open sourced <a href="https://github.com/CleverCloud/issues-helper">issues-helper</a>. It allows you to easily interact with issues on GitHub and GitLab, from the command line.</p>
<pre><code class="language-bash">gli o --assignee clementd --label improvement &quot;Degauss the frobulator fluxfield&quot;
</code></pre>
<p>Let&#39;s see why and how it&#39;s done.</p>
<span id="more-2928"></span>

<h2 id="tldr">TL;DR</h2>
<p>Issues are a good way to keep track of decisions in a project. Opening issues should be easy so people don&#39;t forget to write down why they&#39;ve done things. Opening issues from the command line with minimal fuss is a good thing:</p>
<pre><code class="language-bash">gli init # generate initial configuration
gli o &quot;Issue title&quot; &quot;Optional issue text&quot;
  # add --open to open the issue in the browser once created
  # add --assignee to assign issue
  # add --label to add labels to the issue
gli l # list issues
gli b # open the project homepage in your browser
</code></pre>
<h2 id="issues-use-them">Issues. Use them.</h2>
<p>At Clever Cloud, we use git (and GitLab) a lot. In addition to just using git for code, we also rely a lot on issues. Many discussions end with &quot;please open an issue and sum up what we&#39;ve just said&quot;.</p>
<p>Issues are not just for bugs, we use it as a way to track decisions. Some projects don&#39;t even have code and are just there to track discussions and decisions.</p>
<p>My goal, as a CTO, is to make sure we keep track of all of our decisions. So I need people to open issues, to open them often, and to open them early.</p>
<h2 id="processes-make-em-easy">Processes. Make &#39;em easy.</h2>
<p>I work with people, not with robots. While I trust them and I know they&#39;re good at what they do, I just can&#39;t expect them not to make mistakes, or in that case follow processes with no clear incentive. So I needed to remove friction when opening issues. When we interact with code, it&#39;s from the command line: we craft commits, we deploy to production, we even close issues from the command line (while crafting commits). So we should also open issues from the terminal.</p>
<p>My first try was to use the ruby gitlab CLI, but it had several issues:</p>
<ul>
<li>configuration was done with environment variables</li>
<li>it&#39;s written in ruby and can be complicated to install</li>
<li>the output is more or less database rows in ascii tables</li>
<li>you have to specify which project you&#39;re talking about</li>
</ul>
<p>Even though I&#39;ve written documentation and showed people how to use it, it was not used a lot. When a tool feels like a hack, nobody wants to use it.</p>
<h3 id="what-i-wanted">What I wanted</h3>
<p>I needed two things to get a tool people would use:</p>
<ul>
<li>automatically know which project we&#39;re talking about</li>
<li>config files to avoid having to mess with env variables (and leak GitLab tokens)</li>
</ul>
<p>To avoid ruby installation issues, I&#39;ve decided to use <a href="https://www.rust-lang.org/">Rust</a>. There&#39;s a lot of available libraries, the build system works well, it&#39;s sufficiently expressive to let me express what I want, and in the end I get a nice binary.</p>
<h4 id="xdg-basedir-respect-it">XDG basedir. Respect it.</h4>
<p>Reading GitLab credentials from a file is not really hard. One common mistake is to put config files directly in <code>~</code> like some kind of animal. Instead of cluttering users&#39; home directories, I followed the <a href="https://specifications.freedesktop.org/basedir-spec/basedir-spec-0.6.html">XDG basedir spec</a>. Most languages have a library which handles it for you, so it really is a no-brainer (and it works out of the box on Windows as well).</p>
<h4 id="infer-information-from-context">Infer information from context</h4>
<p>To know where the issues should be opened, <code>issues-helper</code> looks at the <code>origin</code> remote of the current git repo. From that, it knows what to do. Even if you&#39;re not currently in the right repo,</p>
<pre><code class="language-bash">j my-project # autojump is great
gli o &quot;My issue&quot; # that&#39;s it
</code></pre>
<h2 id="tools-open-source-them">Tools. Open Source them.</h2>
<p>Once I had this working, not only people started using this tool, but people improved it: <a href="https://twitter.com/keruspe">@keruspe</a> fixed a lot of issues quite quickly. So the next step was to un-hardcode every Clever Cloud specific things in the codebase (then rebase everything, fun afternoon).</p>
<p>Once it was on GitHub, I got more contributions (from inside and outside). Also, it made me add GitHub support: not being able to use issues-helper to manage its own issues quickly got very frustrating.</p>
<p>Supporting GitHub also made me contribute on the GitHub crate, thus closing a vertuous circle.</p>
<p>There are <a href="https://github.com/CleverCloud/issues-helper/issues">a few issues left</a>. Feel free to chime in, I&#39;ll help you get started. It&#39;s a good way to start working on a Rust project!</p>
<h2 id="how-its-done">How it&#39;s done</h2>
<p>The tool itself doesn&#39;t hold a lot of business logic. It parses a project location from a git remote, reads config from a file, sends a few HTTP requests and displays useful information.</p>
<h3 id="cli-arguments-parsing">CLI arguments parsing</h3>
<p>It&#39;s one of the most important parts of a program, since it&#39;s the UI. The Rust ecosystem has <a href="https://clap.rs/">clap</a> which handles everything: parsing, help and even autocompletion.</p>
<p>Unfortunately, the parsed values are exposed through a <code>Map&lt;String,String&gt;</code>, so even though parsing checks structure, you have to recreate the structure yourself. In practice, you end up with a bunch of <code>value.unwrap(); // this should never fail</code>.</p>
<p>Fortunately, there&#39;s <a href="https://crates.io/crates/structopt">Structopt</a>, which generates clap config from Rust data structures: all the dirty stuff is handled for you, and you get nice structs and enums. Yay!</p>
<h3 id="config-files">Config files</h3>
<p>Config is in a toml file, config file location is handled by the <a href="https://crates.io/crates/xdg">xdg crate</a>. Remember: every time you add files to <code>~</code>, a cute puppy dies.</p>
<h2 id="so">So</h2>
<p>Having processes in a team is a good thing, but if you don&#39;t document them, you can&#39;t expect people to respect them. If processes don&#39;t make everyone&#39;s life easier, you can&#39;t expect people to respect them. One simple way to make processes stick is to provide tooling to make them the easiest path. A bash script is cool, but mainly for its author. A stable CLI tool with a good UI, written in a robust language is not a lot of work and will age <em>way</em> better.</p>
<p><em>Post illustration: The Sorcerer&#39;s Apprentice, Disney Movies. Friden calculating machine. Credits: Disney</em></p>
]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/tools-not-rules-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="tools not rules 1" decoding="async" srcset="https://cdn.clever-cloud.com/uploads/2021/08/tools-not-rules-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/tools-not-rules-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/tools-not-rules-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/tools-not-rules-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/tools-not-rules-1-1368x528.jpg 1368w" sizes="(max-width: 1400px) 100vw, 1400px" /></p><p>A few weeks ago I&#39;ve open sourced <a href="https://github.com/CleverCloud/issues-helper">issues-helper</a>. It allows you to easily interact with issues on GitHub and GitLab, from the command line.</p>
<pre><code class="language-bash">gli o --assignee clementd --label improvement &quot;Degauss the frobulator fluxfield&quot;
</code></pre>
<p>Let&#39;s see why and how it&#39;s done.</p>
<span id="more-2928"></span>

<h2 id="tldr">TL;DR</h2>
<p>Issues are a good way to keep track of decisions in a project. Opening issues should be easy so people don&#39;t forget to write down why they&#39;ve done things. Opening issues from the command line with minimal fuss is a good thing:</p>
<pre><code class="language-bash">gli init # generate initial configuration
gli o &quot;Issue title&quot; &quot;Optional issue text&quot;
  # add --open to open the issue in the browser once created
  # add --assignee to assign issue
  # add --label to add labels to the issue
gli l # list issues
gli b # open the project homepage in your browser
</code></pre>
<h2 id="issues-use-them">Issues. Use them.</h2>
<p>At Clever Cloud, we use git (and GitLab) a lot. In addition to just using git for code, we also rely a lot on issues. Many discussions end with &quot;please open an issue and sum up what we&#39;ve just said&quot;.</p>
<p>Issues are not just for bugs, we use it as a way to track decisions. Some projects don&#39;t even have code and are just there to track discussions and decisions.</p>
<p>My goal, as a CTO, is to make sure we keep track of all of our decisions. So I need people to open issues, to open them often, and to open them early.</p>
<h2 id="processes-make-em-easy">Processes. Make &#39;em easy.</h2>
<p>I work with people, not with robots. While I trust them and I know they&#39;re good at what they do, I just can&#39;t expect them not to make mistakes, or in that case follow processes with no clear incentive. So I needed to remove friction when opening issues. When we interact with code, it&#39;s from the command line: we craft commits, we deploy to production, we even close issues from the command line (while crafting commits). So we should also open issues from the terminal.</p>
<p>My first try was to use the ruby gitlab CLI, but it had several issues:</p>
<ul>
<li>configuration was done with environment variables</li>
<li>it&#39;s written in ruby and can be complicated to install</li>
<li>the output is more or less database rows in ascii tables</li>
<li>you have to specify which project you&#39;re talking about</li>
</ul>
<p>Even though I&#39;ve written documentation and showed people how to use it, it was not used a lot. When a tool feels like a hack, nobody wants to use it.</p>
<h3 id="what-i-wanted">What I wanted</h3>
<p>I needed two things to get a tool people would use:</p>
<ul>
<li>automatically know which project we&#39;re talking about</li>
<li>config files to avoid having to mess with env variables (and leak GitLab tokens)</li>
</ul>
<p>To avoid ruby installation issues, I&#39;ve decided to use <a href="https://www.rust-lang.org/">Rust</a>. There&#39;s a lot of available libraries, the build system works well, it&#39;s sufficiently expressive to let me express what I want, and in the end I get a nice binary.</p>
<h4 id="xdg-basedir-respect-it">XDG basedir. Respect it.</h4>
<p>Reading GitLab credentials from a file is not really hard. One common mistake is to put config files directly in <code>~</code> like some kind of animal. Instead of cluttering users&#39; home directories, I followed the <a href="https://specifications.freedesktop.org/basedir-spec/basedir-spec-0.6.html">XDG basedir spec</a>. Most languages have a library which handles it for you, so it really is a no-brainer (and it works out of the box on Windows as well).</p>
<h4 id="infer-information-from-context">Infer information from context</h4>
<p>To know where the issues should be opened, <code>issues-helper</code> looks at the <code>origin</code> remote of the current git repo. From that, it knows what to do. Even if you&#39;re not currently in the right repo,</p>
<pre><code class="language-bash">j my-project # autojump is great
gli o &quot;My issue&quot; # that&#39;s it
</code></pre>
<h2 id="tools-open-source-them">Tools. Open Source them.</h2>
<p>Once I had this working, not only people started using this tool, but people improved it: <a href="https://twitter.com/keruspe">@keruspe</a> fixed a lot of issues quite quickly. So the next step was to un-hardcode every Clever Cloud specific things in the codebase (then rebase everything, fun afternoon).</p>
<p>Once it was on GitHub, I got more contributions (from inside and outside). Also, it made me add GitHub support: not being able to use issues-helper to manage its own issues quickly got very frustrating.</p>
<p>Supporting GitHub also made me contribute on the GitHub crate, thus closing a vertuous circle.</p>
<p>There are <a href="https://github.com/CleverCloud/issues-helper/issues">a few issues left</a>. Feel free to chime in, I&#39;ll help you get started. It&#39;s a good way to start working on a Rust project!</p>
<h2 id="how-its-done">How it&#39;s done</h2>
<p>The tool itself doesn&#39;t hold a lot of business logic. It parses a project location from a git remote, reads config from a file, sends a few HTTP requests and displays useful information.</p>
<h3 id="cli-arguments-parsing">CLI arguments parsing</h3>
<p>It&#39;s one of the most important parts of a program, since it&#39;s the UI. The Rust ecosystem has <a href="https://clap.rs/">clap</a> which handles everything: parsing, help and even autocompletion.</p>
<p>Unfortunately, the parsed values are exposed through a <code>Map&lt;String,String&gt;</code>, so even though parsing checks structure, you have to recreate the structure yourself. In practice, you end up with a bunch of <code>value.unwrap(); // this should never fail</code>.</p>
<p>Fortunately, there&#39;s <a href="https://crates.io/crates/structopt">Structopt</a>, which generates clap config from Rust data structures: all the dirty stuff is handled for you, and you get nice structs and enums. Yay!</p>
<h3 id="config-files">Config files</h3>
<p>Config is in a toml file, config file location is handled by the <a href="https://crates.io/crates/xdg">xdg crate</a>. Remember: every time you add files to <code>~</code>, a cute puppy dies.</p>
<h2 id="so">So</h2>
<p>Having processes in a team is a good thing, but if you don&#39;t document them, you can&#39;t expect people to respect them. If processes don&#39;t make everyone&#39;s life easier, you can&#39;t expect people to respect them. One simple way to make processes stick is to provide tooling to make them the easiest path. A bash script is cool, but mainly for its author. A stable CLI tool with a good UI, written in a robust language is not a lot of work and will age <em>way</em> better.</p>
<p><em>Post illustration: The Sorcerer&#39;s Apprentice, Disney Movies. Friden calculating machine. Credits: Disney</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Hooks: thank you captain</title>
		<link>https://www.clever.cloud/blog/features/2017/08/10/hooks-thank-you-captain/</link>
		
		<dc:creator><![CDATA[Clement Delafargue]]></dc:creator>
		<pubDate>Thu, 10 Aug 2017 16:20:00 +0000</pubDate>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[deployment]]></category>
		<guid isPermaLink="false">https://www2.cleverapps.io/wp/blog/technology/2017/08/10/hooks-thank-you-captain/</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/hooks-1.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="hooks 1" decoding="async" srcset="https://cdn.clever-cloud.com/uploads/2021/08/hooks-1.png 1400w, https://cdn.clever-cloud.com/uploads/2021/08/hooks-1-300x116.png 300w, https://cdn.clever-cloud.com/uploads/2021/08/hooks-1-1024x395.png 1024w, https://cdn.clever-cloud.com/uploads/2021/08/hooks-1-768x296.png 768w, https://cdn.clever-cloud.com/uploads/2021/08/hooks-1-1368x528.png 1368w" sizes="(max-width: 1400px) 100vw, 1400px" /></p><p>We&#39;ve been quietly rolling out support for hooks during deployments. This may come as a surprise if you listen to our ramblings about deployment processes, as we&#39;ve always pushed for self-contained, zero-adherence builds. Don&#39;t worry, we haven&#39;t changed our minds. Let&#39;s see why and how doing things outside of the build system can make sense.</p>
<span id="more-2898"></span>

<h2 id="our-stance-is-unchanged">Our stance is unchanged</h2>
<p>At Clever Cloud, we&#39;re uncompromizing on automation. The first step to automate production is to have robust, reproducible builds. The best way to be robust and reproducible is to get rid of implicit dependencies: if you have more than two operations to run in sequence to build and run your project, then you have a problem. Not just for deployment, mind you, but for your day-to-day productivity: working on your application becomes complicated, and onboarding new developers takes hours (or worse).</p>
<p>How are Node.JS apps deployed on Clever Cloud? Simple: <code>npm install &amp;&amp; npm start</code>. What about scala applications? <code>sbt stage</code>. No problem, no vendor lock-in. That&#39;s nice and clean. Unfortunately it&#39;s not the whole story.</p>
<h3 id="the-case-of-frontend-build">The case of frontend build</h3>
<p>It&#39;s got to be the most common question we have about our deployment system: &quot;how can I integrate my frontend build in the deployment phase&quot;?</p>
<p>For Node.JS, easy, just add your build phase to <code>scripts.install</code>. For scala applications, you can configure <code>sbt-web</code>. For PHP applications, you can hook in composer. Hooking the frontend build in the main build can range from super easy to <a href="http://dwarffortresswiki.org/index.php?title=DF2014:Fun&amp;redirect=no">dwarf-fortress-fun</a>. Some build tools allow to run arbitrary code, some are more restrictive (but more predictable). For instance, building Haskell applications with <code>stack</code> makes it quite hard to shell out and run <code>npm install</code>.</p>
<h3 id="monolithic-builds-are-not-the-only-option">Monolithic builds are not the only option</h3>
<p>In a full-stack setup (eg Ruby on Rails or Play! framework), integrating the front-end build in the build system is a good idea, as it gives you better integration (eg. <code>play run</code> also refreshes compiled assets). If you&#39;re going with a minimalist tech stack however, integrating everything makes less sense, as your needs for the development environment are not aligned with your needs for the production environment. Let&#39;s say you work on a <code>scotty</code> web app, with some assets compilation. For development, no need to bake everything in the web lib, you can use <a href="https://www.npmjs.com/package/devloop">Devloop</a> and have automatic recompiling on reload, both for frontend and backend.</p>
<p>In that case, instead of shoehorning the frontend build in a <code>stack</code> setup, using a hook as an escape hatch is the most time-effective way to do it; it also gives you more control on when build tasks happen. This allows you to leverage our build system more efficiently.</p>
<h2 id="available-hooks-and-when-to-use-them">Available hooks and when to use them</h2>
<p>A <a href="https://www.clever.cloud/developers/clever-cloud-overview/hooks/">complete rundown of hooks</a> is available in the documentation, but I&#39;ll give you a concrete example to give you a better understanding of what you can do.</p>
<table class="table">
<thead>
<tr>
<th width="200">Hook</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>`pre build`</td>
<td>This is a good place to run `npm install`, as it happens before the deps are cached: that way you benefit from dependencies caching for both frontend and backend builds.</td>
</tr>
<tr>
<td>`post build`</td>
<td>That's where you want to run the actual build target. It happens before the built artifact is saved, this way the frontend build is bundled with the rest of the compiled files.</td>
</tr>
<tr>
<td>`pre run`</td>
<td>That's only for specific setup you want to run every time (even when deploying from cache).</td>
</tr>
<tr>
<td>`run succeeded` and `run failed`</td>
<td>These are mostly for notification purposes, as they happen when the application has already started (or failed to start). They can't abort the launch, so they're just there for debugging or notification purposes.</td>
</tr>
</tbody>
</table>

<h2 id="please-give-us-feedback">Please give us feedback</h2>
<p>I&#39;ve created the new hooks system to scratch an itch, so it may change a bit in the following months. Please reach out to the <a href="mailto:support@clever-cloud.com">support team</a> if you have questions or suggestions.</p>
]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/hooks-1.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="hooks 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/hooks-1.png 1400w, https://cdn.clever-cloud.com/uploads/2021/08/hooks-1-300x116.png 300w, https://cdn.clever-cloud.com/uploads/2021/08/hooks-1-1024x395.png 1024w, https://cdn.clever-cloud.com/uploads/2021/08/hooks-1-768x296.png 768w, https://cdn.clever-cloud.com/uploads/2021/08/hooks-1-1368x528.png 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>We&#39;ve been quietly rolling out support for hooks during deployments. This may come as a surprise if you listen to our ramblings about deployment processes, as we&#39;ve always pushed for self-contained, zero-adherence builds. Don&#39;t worry, we haven&#39;t changed our minds. Let&#39;s see why and how doing things outside of the build system can make sense.</p>
<span id="more-2898"></span>

<h2 id="our-stance-is-unchanged">Our stance is unchanged</h2>
<p>At Clever Cloud, we&#39;re uncompromizing on automation. The first step to automate production is to have robust, reproducible builds. The best way to be robust and reproducible is to get rid of implicit dependencies: if you have more than two operations to run in sequence to build and run your project, then you have a problem. Not just for deployment, mind you, but for your day-to-day productivity: working on your application becomes complicated, and onboarding new developers takes hours (or worse).</p>
<p>How are Node.JS apps deployed on Clever Cloud? Simple: <code>npm install &amp;&amp; npm start</code>. What about scala applications? <code>sbt stage</code>. No problem, no vendor lock-in. That&#39;s nice and clean. Unfortunately it&#39;s not the whole story.</p>
<h3 id="the-case-of-frontend-build">The case of frontend build</h3>
<p>It&#39;s got to be the most common question we have about our deployment system: &quot;how can I integrate my frontend build in the deployment phase&quot;?</p>
<p>For Node.JS, easy, just add your build phase to <code>scripts.install</code>. For scala applications, you can configure <code>sbt-web</code>. For PHP applications, you can hook in composer. Hooking the frontend build in the main build can range from super easy to <a href="http://dwarffortresswiki.org/index.php?title=DF2014:Fun&amp;redirect=no">dwarf-fortress-fun</a>. Some build tools allow to run arbitrary code, some are more restrictive (but more predictable). For instance, building Haskell applications with <code>stack</code> makes it quite hard to shell out and run <code>npm install</code>.</p>
<h3 id="monolithic-builds-are-not-the-only-option">Monolithic builds are not the only option</h3>
<p>In a full-stack setup (eg Ruby on Rails or Play! framework), integrating the front-end build in the build system is a good idea, as it gives you better integration (eg. <code>play run</code> also refreshes compiled assets). If you&#39;re going with a minimalist tech stack however, integrating everything makes less sense, as your needs for the development environment are not aligned with your needs for the production environment. Let&#39;s say you work on a <code>scotty</code> web app, with some assets compilation. For development, no need to bake everything in the web lib, you can use <a href="https://www.npmjs.com/package/devloop">Devloop</a> and have automatic recompiling on reload, both for frontend and backend.</p>
<p>In that case, instead of shoehorning the frontend build in a <code>stack</code> setup, using a hook as an escape hatch is the most time-effective way to do it; it also gives you more control on when build tasks happen. This allows you to leverage our build system more efficiently.</p>
<h2 id="available-hooks-and-when-to-use-them">Available hooks and when to use them</h2>
<p>A <a href="https://www.clever.cloud/developers/clever-cloud-overview/hooks/">complete rundown of hooks</a> is available in the documentation, but I&#39;ll give you a concrete example to give you a better understanding of what you can do.</p>
<table class="table">
<thead>
<tr>
<th width="200">Hook</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>`pre build`</td>
<td>This is a good place to run `npm install`, as it happens before the deps are cached: that way you benefit from dependencies caching for both frontend and backend builds.</td>
</tr>
<tr>
<td>`post build`</td>
<td>That's where you want to run the actual build target. It happens before the built artifact is saved, this way the frontend build is bundled with the rest of the compiled files.</td>
</tr>
<tr>
<td>`pre run`</td>
<td>That's only for specific setup you want to run every time (even when deploying from cache).</td>
</tr>
<tr>
<td>`run succeeded` and `run failed`</td>
<td>These are mostly for notification purposes, as they happen when the application has already started (or failed to start). They can't abort the launch, so they're just there for debugging or notification purposes.</td>
</tr>
</tbody>
</table>

<h2 id="please-give-us-feedback">Please give us feedback</h2>
<p>I&#39;ve created the new hooks system to scratch an itch, so it may change a bit in the following months. Please reach out to the <a href="mailto:support@clever-cloud.com">support team</a> if you have questions or suggestions.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>New version of our CLI: clever-tools 0.7.0 released</title>
		<link>https://www.clever.cloud/blog/features/2017/02/09/clever-tools-release/</link>
		
		<dc:creator><![CDATA[Clement Delafargue]]></dc:creator>
		<pubDate>Thu, 09 Feb 2017 16:17:00 +0000</pubDate>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[feature]]></category>
		<category><![CDATA[ssh]]></category>
		<guid isPermaLink="false">https://www2.cleverapps.io/wp/blog/technology/2017/02/09/clever-tools-release/</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/clever-tools-update-1.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="clever tools update 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/clever-tools-update-1.png 1400w, https://cdn.clever-cloud.com/uploads/2021/08/clever-tools-update-1-300x116.png 300w, https://cdn.clever-cloud.com/uploads/2021/08/clever-tools-update-1-1024x395.png 1024w, https://cdn.clever-cloud.com/uploads/2021/08/clever-tools-update-1-768x296.png 768w, https://cdn.clever-cloud.com/uploads/2021/08/clever-tools-update-1-1368x528.png 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>Since <a href="https://www.clever.cloud/blog/features/2015/09/21/public-api-available/">its first release</a>, we&#39;ve been quietly improving our CLI tool, <code>clever-tools</code>. Today, we&#39;ve released version <code>0.7.0</code>, with better support for node 7 and many improvements.</p>
<span id="more-2886"></span>

<h3 id="new-features-in-070">New features in 0.7.0</h3>
<p>The most important change is better support for node 7. The installation phase is now way faster for node 7 users.</p>
<p>Another important feature is <code>clever ssh</code>, available in preview mode for <code>clever-tools</code> users.  <code>clever ssh</code> allows you to ssh into a running instance for debugging purposes (eg. list files, view logs locally, …). Please get in touch with the <a href="mailto:support@clever-cloud.com">support</a> if you want to try it out.  We&#39;ll release complete documentation and examples once this feature hits GA.</p>
<h3 id="why-use-clever-tools">Why use Clever Tools?</h3>
<p>The web console is nice to use and doesn&#39;t require any installation. Why bother with <code>clever-tools</code> then? Here are a few use cases where <code>clever-tools</code> really shines.</p>
<h4 id="perfect-for-terminal-heavy-multitaskers">Perfect for terminal-heavy multitaskers</h4>
<p>If, like me, you&#39;re working on several projects in several terminal windows, going back to the web console to check logs and deployments can get tedious. With <code>clever-tools</code>, you can work on different projects without ever leaving your comfy terminal window. You can launch 5 deployments in parallel and see how they go, side-by-side without having to switch from app to app in your browser.</p>
<h4 id="fine-grained-access-to-logs">Fine-grained access to logs</h4>
<p>The web console is great for displaying logs as they come, but reading old logs requires a lot of scrolling. If you want to inspect logs around a specific date/time to investigate e.g. a user report, worry not:</p>
<pre><code class="language-bash">clever logs --after &quot;2017-02-08T08:28&quot; --before &quot;2017-02-08T08:32&quot;
</code></pre>
<p>Also, if you want to search for a specific term you can just <code>grep</code> the output:</p>
<pre><code class="language-bash">clever logs | grep NullPointerException
</code></pre>
<p>The best part: new lines will appear in real time.</p>
<h4 id="no-ssh-configuration-necessary">No SSH configuration necessary</h4>
<p>From version <code>0.6.0</code> upwards, <code>clever deploy</code> pushes over HTTPS and doesn&#39;t require SSH configuration. If your platform makes ssh configuration more difficult than it should be (I&#39;m looking at you, Windows), then just use <code>clever deploy</code>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/clever-tools-update-1.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="clever tools update 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/clever-tools-update-1.png 1400w, https://cdn.clever-cloud.com/uploads/2021/08/clever-tools-update-1-300x116.png 300w, https://cdn.clever-cloud.com/uploads/2021/08/clever-tools-update-1-1024x395.png 1024w, https://cdn.clever-cloud.com/uploads/2021/08/clever-tools-update-1-768x296.png 768w, https://cdn.clever-cloud.com/uploads/2021/08/clever-tools-update-1-1368x528.png 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>Since <a href="https://www.clever.cloud/blog/features/2015/09/21/public-api-available/">its first release</a>, we&#39;ve been quietly improving our CLI tool, <code>clever-tools</code>. Today, we&#39;ve released version <code>0.7.0</code>, with better support for node 7 and many improvements.</p>
<span id="more-2886"></span>

<h3 id="new-features-in-070">New features in 0.7.0</h3>
<p>The most important change is better support for node 7. The installation phase is now way faster for node 7 users.</p>
<p>Another important feature is <code>clever ssh</code>, available in preview mode for <code>clever-tools</code> users.  <code>clever ssh</code> allows you to ssh into a running instance for debugging purposes (eg. list files, view logs locally, …). Please get in touch with the <a href="mailto:support@clever-cloud.com">support</a> if you want to try it out.  We&#39;ll release complete documentation and examples once this feature hits GA.</p>
<h3 id="why-use-clever-tools">Why use Clever Tools?</h3>
<p>The web console is nice to use and doesn&#39;t require any installation. Why bother with <code>clever-tools</code> then? Here are a few use cases where <code>clever-tools</code> really shines.</p>
<h4 id="perfect-for-terminal-heavy-multitaskers">Perfect for terminal-heavy multitaskers</h4>
<p>If, like me, you&#39;re working on several projects in several terminal windows, going back to the web console to check logs and deployments can get tedious. With <code>clever-tools</code>, you can work on different projects without ever leaving your comfy terminal window. You can launch 5 deployments in parallel and see how they go, side-by-side without having to switch from app to app in your browser.</p>
<h4 id="fine-grained-access-to-logs">Fine-grained access to logs</h4>
<p>The web console is great for displaying logs as they come, but reading old logs requires a lot of scrolling. If you want to inspect logs around a specific date/time to investigate e.g. a user report, worry not:</p>
<pre><code class="language-bash">clever logs --after &quot;2017-02-08T08:28&quot; --before &quot;2017-02-08T08:32&quot;
</code></pre>
<p>Also, if you want to search for a specific term you can just <code>grep</code> the output:</p>
<pre><code class="language-bash">clever logs | grep NullPointerException
</code></pre>
<p>The best part: new lines will appear in real time.</p>
<h4 id="no-ssh-configuration-necessary">No SSH configuration necessary</h4>
<p>From version <code>0.6.0</code> upwards, <code>clever deploy</code> pushes over HTTPS and doesn&#39;t require SSH configuration. If your platform makes ssh configuration more difficult than it should be (I&#39;m looking at you, Windows), then just use <code>clever deploy</code>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>null is not the issue</title>
		<link>https://www.clever.cloud/blog/engineering/2016/07/21/null-is-not-the-issue/</link>
		
		<dc:creator><![CDATA[Clement Delafargue]]></dc:creator>
		<pubDate>Thu, 21 Jul 2016 14:56:00 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[thoughts]]></category>
		<category><![CDATA[workflow]]></category>
		<guid isPermaLink="false">https://www2.cleverapps.io/wp/blog/technology/2016/07/21/null-is-not-the-issue/</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/null-issue-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="null issue 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/null-issue-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/null-issue-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/null-issue-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/null-issue-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/null-issue-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>Nowadays, we know that <code>null</code> is to be avoided. It&#39;s been dubbed the <em>billion dollar mistake</em> by its own creator, and the dreaded <code>NullPointerException</code> everyone knows about. Yet, when it comes to getting rid of <code>null</code>s, nobody agrees.</p>
<span id="more-2806"></span>

<h2 id="null-is-bad-mkay"><code>null</code> is bad, m&#39;kay</h2>
<ul>
<li>NPEs</li>
<li>hard to read (is this value always defined?)</li>
<li>handling possibly undefined values is tedious</li>
</ul>
<p>The issue is that we focus on <code>null</code>, and not on the actual problems it causes. If your only goal is to get rid of NPEs at all costs, then you will pay those costs. Dearly.</p>
<p>The memory safety issues caused by <code>null</code> are solved on most platforms. In many languages, <code>null</code> is a pointer to a specific value with specific properties, so not literally a null pointer anymore, and on modern OSs, the memory protection system will prevent your code from directly accessing the address <code>0x00</code>.</p>
<p>So the big risk is having your program blow up (<code>NPE</code>, <code>segfault</code>, <code>panic</code>, …) because of an unexpected missing value. The core issue is that you were unable to express that the value was possibly missing; the crash is a consequence of this issue. Yet many people try to solve the issue by preventing the crash (null check, <a href="https://en.wikipedia.org/wiki/Null_Object_pattern">null object pattern</a>, …) instead of handling the core issue: a value could be missing and you weren&#39;t able to express it.</p>
<h2 id="stop-chasing-npes-and-fix-your-domain-model">Stop chasing NPEs and fix your domain model</h2>
<p>If you&#39;re trying to get rid of NPEs by removing the difference between &quot;there is a meaningful value&quot; and &quot;there is no value&quot;, then not only you&#39;re not solving your issue, but you&#39;re making it far, far worse.</p>
<p>Your domain model didn&#39;t let you express statically the possible absence of a value, but the presence of null at least gave you a stuctural difference at runtime. That&#39;s why putting default values or worse, following the null object pattern, is terrible. You had structural information, but couldn&#39;t use it in a rigorous way, so you&#39;re just throwing it all away because of an implementation detail.</p>
<p>If you&#39;re searching for a replacement to <code>null</code> to denote missing values, it has to be structurally different from a regular value (it cannot belong to the domain of the value you may have). So if you&#39;re in a typed system, then a value that may be not there has to have a different type from a value that&#39;s definitely there. In an untyped language, you can&#39;t have a static difference, so using <code>null</code> is kind of OK (though there are better solutions).</p>
<p>For example, in java you can do:</p>
<pre><code class="language-java">// Bad
String notThere = null;
String there = &quot;my string&quot;;
// Turbo-bad
String notThere = &quot;&quot;; // or &quot;N/A&quot;, etc
String there = &quot;my string&quot;;
// Good
Optional&lt;String&gt; notThere = Optional.empty();
Optional&lt;String&gt; there = Optional.of(&quot;my string&quot;);
</code></pre>
<p>With optional, not only you have a structural difference between defined and undefined strings (instead of having to check if the string is equal to <code>&quot;&quot;</code> or <code>&quot;N/A&quot;</code>, without any guarantee that it&#39;s not the actual value), but it&#39;s clearly documented in the type.</p>
<p><code>Optional</code> is available in Java 8 (and in Guava if you&#39;re not using java 8 yet). In scala, rust, ocaml and many other languages, it&#39;s called <code>Option</code>, in Haskell it&#39;s called <code>Maybe</code>.</p>
<h2 id="this-is-why-you-can-have-nice-things">This is why you <em>can</em> have nice things</h2>
<p>Ok so now you have a proper representation for your optional values. In a typed language it means that you&#39;re forced to check if the value is already there before using it.</p>
<p>For instance, in java:</p>
<pre><code class="language-java">Optional&lt;Integer&gt; parseOptionalString(Optional&lt;String&gt; myOptionalString) {
    if(myOptionalString.isPresent()) {
        Optional&lt;Integer&gt; result = parseInt(myOptionalString.get());
        return result;
    } else {
        return Optional.empty();
    }
}
</code></pre>
<p>This works perfectly well, but is still as verbose as using explicit <code>null</code> checks. So if you&#39;re only concerned about code terseness (you really shouldn&#39;t), it can feel like a marginal improvement (it&#39;s way better than that).</p>
<p>Thankfully that&#39;s not the idiomatic way of handling <code>Optional</code> values: now that we can denote the abstract concept of <em>being possibly not there</em> (in this case, <code>Optional&lt;_&gt;</code>), then we can do useful stuff about it:</p>
<ul>
<li>transforming it only if it&#39;s defined (with <code>map</code>)</li>
<li>eliminate the option by providing a default value when we don&#39;t need the
information anymore (with <code>orElseGet</code>)</li>
<li>sequencing several operations returning options (with <code>flatMap</code>)</li>
</ul>
<p>All of this comes for free because we were able to clearly define our domain model. Some languages like Kotlin provide approaching solutions with things like the Safe Call Operator for chaining operations (instead of using <code>map</code> and <code>flatMap</code>) and the Elvis Operator for providing default values. This, however, is less extensible and less composable than having proper options (<code>map</code> and <code>flatMap</code> are not specific to <code>Optional</code>).</p>
<pre><code class="language-java">Optional&lt;Integer&gt; parseOptionalString(Optional&lt;String&gt; myOptionalString) {
    return myOptionalString.flatMap(parseInt);
}
</code></pre>
<p>Once you have properly defined your domain model, then you can have cleaner code thanks to the information encoded in your types. Aiming at terser code without proper abstraction will lead you to perlish nightmares.</p>
<h2 id="to-sum-up">To sum up</h2>
<p>Using <code>null</code> causes problems. Resorting to solutions that erase information (setting a default value too early or worse, the null object pattern) will cause graver and subtler problems.</p>
<p>In order of decreasing importance, the problems with <code>null</code> are:</p>
<ol>
<li>it&#39;s not clear for people if a value can be missing</li>
<li>the program can blow up if somebody forgot to handle a missing value</li>
<li>it&#39;s tedious to sequence operations returning null</li>
</ol>
<p>Don&#39;t settle for solutions that only address #2 and #3.</p>
]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/null-issue-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="null issue 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/null-issue-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/null-issue-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/null-issue-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/null-issue-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/null-issue-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>Nowadays, we know that <code>null</code> is to be avoided. It&#39;s been dubbed the <em>billion dollar mistake</em> by its own creator, and the dreaded <code>NullPointerException</code> everyone knows about. Yet, when it comes to getting rid of <code>null</code>s, nobody agrees.</p>
<span id="more-2806"></span>

<h2 id="null-is-bad-mkay"><code>null</code> is bad, m&#39;kay</h2>
<ul>
<li>NPEs</li>
<li>hard to read (is this value always defined?)</li>
<li>handling possibly undefined values is tedious</li>
</ul>
<p>The issue is that we focus on <code>null</code>, and not on the actual problems it causes. If your only goal is to get rid of NPEs at all costs, then you will pay those costs. Dearly.</p>
<p>The memory safety issues caused by <code>null</code> are solved on most platforms. In many languages, <code>null</code> is a pointer to a specific value with specific properties, so not literally a null pointer anymore, and on modern OSs, the memory protection system will prevent your code from directly accessing the address <code>0x00</code>.</p>
<p>So the big risk is having your program blow up (<code>NPE</code>, <code>segfault</code>, <code>panic</code>, …) because of an unexpected missing value. The core issue is that you were unable to express that the value was possibly missing; the crash is a consequence of this issue. Yet many people try to solve the issue by preventing the crash (null check, <a href="https://en.wikipedia.org/wiki/Null_Object_pattern">null object pattern</a>, …) instead of handling the core issue: a value could be missing and you weren&#39;t able to express it.</p>
<h2 id="stop-chasing-npes-and-fix-your-domain-model">Stop chasing NPEs and fix your domain model</h2>
<p>If you&#39;re trying to get rid of NPEs by removing the difference between &quot;there is a meaningful value&quot; and &quot;there is no value&quot;, then not only you&#39;re not solving your issue, but you&#39;re making it far, far worse.</p>
<p>Your domain model didn&#39;t let you express statically the possible absence of a value, but the presence of null at least gave you a stuctural difference at runtime. That&#39;s why putting default values or worse, following the null object pattern, is terrible. You had structural information, but couldn&#39;t use it in a rigorous way, so you&#39;re just throwing it all away because of an implementation detail.</p>
<p>If you&#39;re searching for a replacement to <code>null</code> to denote missing values, it has to be structurally different from a regular value (it cannot belong to the domain of the value you may have). So if you&#39;re in a typed system, then a value that may be not there has to have a different type from a value that&#39;s definitely there. In an untyped language, you can&#39;t have a static difference, so using <code>null</code> is kind of OK (though there are better solutions).</p>
<p>For example, in java you can do:</p>
<pre><code class="language-java">// Bad
String notThere = null;
String there = &quot;my string&quot;;
// Turbo-bad
String notThere = &quot;&quot;; // or &quot;N/A&quot;, etc
String there = &quot;my string&quot;;
// Good
Optional&lt;String&gt; notThere = Optional.empty();
Optional&lt;String&gt; there = Optional.of(&quot;my string&quot;);
</code></pre>
<p>With optional, not only you have a structural difference between defined and undefined strings (instead of having to check if the string is equal to <code>&quot;&quot;</code> or <code>&quot;N/A&quot;</code>, without any guarantee that it&#39;s not the actual value), but it&#39;s clearly documented in the type.</p>
<p><code>Optional</code> is available in Java 8 (and in Guava if you&#39;re not using java 8 yet). In scala, rust, ocaml and many other languages, it&#39;s called <code>Option</code>, in Haskell it&#39;s called <code>Maybe</code>.</p>
<h2 id="this-is-why-you-can-have-nice-things">This is why you <em>can</em> have nice things</h2>
<p>Ok so now you have a proper representation for your optional values. In a typed language it means that you&#39;re forced to check if the value is already there before using it.</p>
<p>For instance, in java:</p>
<pre><code class="language-java">Optional&lt;Integer&gt; parseOptionalString(Optional&lt;String&gt; myOptionalString) {
    if(myOptionalString.isPresent()) {
        Optional&lt;Integer&gt; result = parseInt(myOptionalString.get());
        return result;
    } else {
        return Optional.empty();
    }
}
</code></pre>
<p>This works perfectly well, but is still as verbose as using explicit <code>null</code> checks. So if you&#39;re only concerned about code terseness (you really shouldn&#39;t), it can feel like a marginal improvement (it&#39;s way better than that).</p>
<p>Thankfully that&#39;s not the idiomatic way of handling <code>Optional</code> values: now that we can denote the abstract concept of <em>being possibly not there</em> (in this case, <code>Optional&lt;_&gt;</code>), then we can do useful stuff about it:</p>
<ul>
<li>transforming it only if it&#39;s defined (with <code>map</code>)</li>
<li>eliminate the option by providing a default value when we don&#39;t need the
information anymore (with <code>orElseGet</code>)</li>
<li>sequencing several operations returning options (with <code>flatMap</code>)</li>
</ul>
<p>All of this comes for free because we were able to clearly define our domain model. Some languages like Kotlin provide approaching solutions with things like the Safe Call Operator for chaining operations (instead of using <code>map</code> and <code>flatMap</code>) and the Elvis Operator for providing default values. This, however, is less extensible and less composable than having proper options (<code>map</code> and <code>flatMap</code> are not specific to <code>Optional</code>).</p>
<pre><code class="language-java">Optional&lt;Integer&gt; parseOptionalString(Optional&lt;String&gt; myOptionalString) {
    return myOptionalString.flatMap(parseInt);
}
</code></pre>
<p>Once you have properly defined your domain model, then you can have cleaner code thanks to the information encoded in your types. Aiming at terser code without proper abstraction will lead you to perlish nightmares.</p>
<h2 id="to-sum-up">To sum up</h2>
<p>Using <code>null</code> causes problems. Resorting to solutions that erase information (setting a default value too early or worse, the null object pattern) will cause graver and subtler problems.</p>
<p>In order of decreasing importance, the problems with <code>null</code> are:</p>
<ol>
<li>it&#39;s not clear for people if a value can be missing</li>
<li>the program can blow up if somebody forgot to handle a missing value</li>
<li>it&#39;s tedious to sequence operations returning null</li>
</ol>
<p>Don&#39;t settle for solutions that only address #2 and #3.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Introducing Service Dependencies</title>
		<link>https://www.clever.cloud/blog/features/2016/06/23/introducing-service-dependencies/</link>
		
		<dc:creator><![CDATA[Clement Delafargue]]></dc:creator>
		<pubDate>Thu, 23 Jun 2016 17:15:00 +0000</pubDate>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[addons]]></category>
		<category><![CDATA[dependencies]]></category>
		<category><![CDATA[microservices]]></category>
		<guid isPermaLink="false">https://www2.cleverapps.io/wp/blog/technology/2016/06/23/introducing-service-dependencies/</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/service-deps-banner-1.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="service deps banner 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/service-deps-banner-1.png 1400w, https://cdn.clever-cloud.com/uploads/2021/08/service-deps-banner-1-300x116.png 300w, https://cdn.clever-cloud.com/uploads/2021/08/service-deps-banner-1-1024x395.png 1024w, https://cdn.clever-cloud.com/uploads/2021/08/service-deps-banner-1-768x296.png 768w, https://cdn.clever-cloud.com/uploads/2021/08/service-deps-banner-1-1368x528.png 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>At Clever Cloud, we&#39;ve started using microservices before it was cool&#8482;. Today we&#39;re excited to launch service dependencies, to simplify microservices management.  <span id="more-2867"></span></p>
<h2 id="the-microservices-graph">The microservices graph</h2>
<p>When you ditch your monolith and go full microservices, your application becomes a graph of loosely coupled microservices.</p>
<p>For instance, an typical service API can depend on:</p>
<ul>
<li>an auth microservice to validate requests</li>
<li>a notification gateway to send notification</li>
</ul>
<p>In turn, the notification gateway can depend on:</p>
<ul>
<li>an email gateway</li>
<li>a push notification gateway</li>
</ul>
<p>So you have a graph of services, each with its own lifecycle (eg dev, staging, production). So if you want to use a different email gateway from your staging API, you need to have in turn a specific notification gateway. To make a test in one project, you need to modifiy code in all its dependency chain. Uncool</p>
<h2 id="service-dependencies">Service dependencies</h2>
<p>On Clever Cloud, you already know how to link applications to their dependencies on the fly, without touching code or fidling with config files: by linking an addon to your application, you let the addon inject its location and credentials so you don&#39;t have to handle it yourself. Service dependencies is just a generalization of the addon mechanism to any application.</p>
<h3 id="link-applications">Link applications</h3>
<p>You can add dependencies to an application either from the CLI:</p>
<pre><code class="language-bash">  clever service --alias api link-app notification-gateway
</code></pre>
<p>or from the console:</p>
<p><img src="https://www2.cleverapps.io/app/uploads/2021/08/service-dependencies.png" alt=""></p>
<h3 id="exposed-configuration">Exposed configuration</h3>
<p>With addons, the exposed configuration is always the same. With applications, you can declare the configuration you want to expose to your dependents. To make an app expose configuration, you can either do it from the CLI:</p>
<pre><code class="language-bash">  clever exposed-config --alias api set API_DOMAIN_NAME api.example.com
</code></pre>
<p>or from the console:</p>
<p><img src="https://www2.cleverapps.io/app/uploads/2021/08/exposed-config.png" alt=""></p>
<p>Note: every time you update the exposed configuration, dependent applications will be automatically redeployed.</p>
]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/service-deps-banner-1.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="service deps banner 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/service-deps-banner-1.png 1400w, https://cdn.clever-cloud.com/uploads/2021/08/service-deps-banner-1-300x116.png 300w, https://cdn.clever-cloud.com/uploads/2021/08/service-deps-banner-1-1024x395.png 1024w, https://cdn.clever-cloud.com/uploads/2021/08/service-deps-banner-1-768x296.png 768w, https://cdn.clever-cloud.com/uploads/2021/08/service-deps-banner-1-1368x528.png 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>At Clever Cloud, we&#39;ve started using microservices before it was cool&#8482;. Today we&#39;re excited to launch service dependencies, to simplify microservices management.  <span id="more-2867"></span></p>
<h2 id="the-microservices-graph">The microservices graph</h2>
<p>When you ditch your monolith and go full microservices, your application becomes a graph of loosely coupled microservices.</p>
<p>For instance, an typical service API can depend on:</p>
<ul>
<li>an auth microservice to validate requests</li>
<li>a notification gateway to send notification</li>
</ul>
<p>In turn, the notification gateway can depend on:</p>
<ul>
<li>an email gateway</li>
<li>a push notification gateway</li>
</ul>
<p>So you have a graph of services, each with its own lifecycle (eg dev, staging, production). So if you want to use a different email gateway from your staging API, you need to have in turn a specific notification gateway. To make a test in one project, you need to modifiy code in all its dependency chain. Uncool</p>
<h2 id="service-dependencies">Service dependencies</h2>
<p>On Clever Cloud, you already know how to link applications to their dependencies on the fly, without touching code or fidling with config files: by linking an addon to your application, you let the addon inject its location and credentials so you don&#39;t have to handle it yourself. Service dependencies is just a generalization of the addon mechanism to any application.</p>
<h3 id="link-applications">Link applications</h3>
<p>You can add dependencies to an application either from the CLI:</p>
<pre><code class="language-bash">  clever service --alias api link-app notification-gateway
</code></pre>
<p>or from the console:</p>
<p><img src="https://www2.cleverapps.io/app/uploads/2021/08/service-dependencies.png" alt=""></p>
<h3 id="exposed-configuration">Exposed configuration</h3>
<p>With addons, the exposed configuration is always the same. With applications, you can declare the configuration you want to expose to your dependents. To make an app expose configuration, you can either do it from the CLI:</p>
<pre><code class="language-bash">  clever exposed-config --alias api set API_DOMAIN_NAME api.example.com
</code></pre>
<p>or from the console:</p>
<p><img src="https://www2.cleverapps.io/app/uploads/2021/08/exposed-config.png" alt=""></p>
<p>Note: every time you update the exposed configuration, dependent applications will be automatically redeployed.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Why Auto Increment Is A Terrible Idea</title>
		<link>https://www.clever.cloud/blog/engineering/2015/05/20/why-auto-increment-is-a-terrible-idea/</link>
		
		<dc:creator><![CDATA[Clement Delafargue]]></dc:creator>
		<pubDate>Wed, 20 May 2015 11:03:00 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[postgresql]]></category>
		<guid isPermaLink="false">https://www2.cleverapps.io/wp/blog/technology/2015/05/20/why-auto-increment-is-a-terrible-idea/</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2020/12/primary-key-type-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="primary key type 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2020/12/primary-key-type-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2020/12/primary-key-type-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2020/12/primary-key-type-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2020/12/primary-key-type-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2020/12/primary-key-type-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>As big users of PostgreSQL, we had the opportunity of re-thinking the idioms common in the world of relational DBs.</p>
<p>Today, I&#39;ll talk about why we stopped using serial integers for our primary keys, and why we&#39;re now extensively using Universally Unique IDs (or UUIDs) almost everywhere.</p>
<h3 id="tldr">TL;DR</h3>
<p>Use UUIDs as primary keys. They can be freely exposed without disclosing sensitive information, they are not predictable and they are performant.</p>
<span id="more-2799"></span>

<h3 id="primary-keys-technical-keys-and-semantic-keys">Primary keys, technical keys and semantic keys</h3>
<p>A relational database is a graph where nodes are called entities and edges relations. To be able to express a relation between entities, we need to be able to uniquely refer to any entity: that&#39;s the role of a primary key.</p>
<p>The role of a primary key is to provide a stable, indexable reference to an entity. You have two ways to construct your primary key: either as a <em>semantic</em> key, or as a <em>technical</em> key.</p>
<p>A <em>semantic</em> primary key is extracted from the entities attributes (ie you use one or several fields of your entity as its primary key).</p>
<p>A <em>technical</em> primary key is completely unrelated to the fields of its entity. It&#39;s constructed when the entity is inserted in the DB.</p>
<p>Ideally, semantic keys would be better, as it allows for a very simple way to understand and compare entities. But relational DBs are built upon a fundamentally mutable model. The current state of the world is stored in the database, and entities are subject to mutation. Relational DBs are <strong>very</strong> good at storing a <em>relatively</em> small amount of data, and are not well suited for immutable databases.</p>
<p>That&#39;s why to be able to have <strong>stable</strong> primary keys, we commonly resort to <em>serial IDs</em>. Serial IDs are a technical key, as they&#39;re not related to the actual contents of its entity.</p>
<p>To be fair, you can configure your foreign key to have <code>ON UPDATE CASCADE</code> to have primary key updates automatically propagated everywhere within the database, but it doesn&#39;t solve the problem if you&#39;ve exposed primary key values outside the DB.</p>
<h4 id="whats-a-serial-id">What&#39;s a serial ID?</h4>
<p>Basically, a serial id is a number that increases everytime you insert a row. The database does the bookkeeping for you, so it&#39;s transparent for the developer.</p>
<pre><code class="language-sql">create table entity(
  entity_id serial primary key,
  attribute text not null
);
</code></pre>
<p>We can then insert values in the table; postgres will handle the <code>entity_id</code> field.</p>
<pre><code class="language-sql">&gt; insert into entity (attribute) values (&#39;ohai&#39;);
INSERT 0 1

&gt; select * from entity;
    entity_id | attribute 
-----------+-----------
            1 | ohai
(1 row)
</code></pre>
<p>The row has been inserted, and the entity has an automatically attributed id. In postgresql, <code>serial</code> is implemented through a <em>sequence</em>, which acts a bit like a counter. We can inspect its current state:</p>
<pre><code class="language-sql">&gt; select currval(&#39;entity_entity_id_seq&#39;::regclass);
currval 
---------
        1
(1 row)
</code></pre>
<p>OK, so we have a perfectly good primary key for our entities. What&#39;s the problem?</p>
<h3 id="why-serial-ids-can-be-a-problem">Why serial IDs can be a problem</h3>
<h4 id="information-disclosure">Information disclosure</h4>
<p>The current value corresponds to the last value used as a primary key. Since the sequence starts at 1 and is incremented 1 by 1, <code>currval</code> roughly corresponds in our case to the number of rows in the table (not exactly, because of deletions).</p>
<p>So, if you want to count the number of rows in a given table, all you have to do is to have the system generate a new entity and inspect its ID.</p>
<p>So, do users have access to primary keys? The answer is often yes: primary keys are very often exposed to the user, most often in URLs, as we want URLs to be stable (see <a href="http://www.w3.org/Provider/Style/URI.html">cool URIs don&#39;t change</a>).</p>
<p>Let&#39;s say you&#39;re a company operating a SaaS, <strong>all it takes to know your user count is to create an account</strong>. A number of social networks boasting impressive user bases were pwn3d this way. Just by creating an account and looking at a link.</p>
<h4 id="entity-enumerations">Entity enumerations</h4>
<p>An even bigger problem is that it&#39;s very easy to enumerate the entities in any given table. You start from 1, and you keep on incrementing the value. It becomes very easy to scrape all your entities. It leads to spamming (just don&#39;t start from 1, as you don&#39;t want to spam the admin team ;-) ), or worse. If you have light access control, only based on the knowledge of a given URL, then anybody can display private information.</p>
<h4 id="non-uniqueness-across-tables">Non uniqueness across tables</h4>
<p>Since each table has its own sequence, an identical value will be found as the primary key of different entities. Now imagine you make a tab-completed typo when deleting a row. Yeah, you&#39;ve just deleted an arbitrary row somewhere in your DB. Let&#39;s hope you don&#39;t have too many <code>ON DELETE CASCADE</code> configured.</p>
<h3 id="workarounds">Workarounds</h3>
<p>You can configure your sequence to start at an arbitrary point, have an increment bigger than one, or even share the sequence between tables. In any case, you&#39;re still disclosing information about your growth, and you&#39;ll just reach integer overflow quicker. Not really a perfect solution.</p>
<h3 id="a-word-on-uuids">A word on UUIDs</h3>
<p>You may already have seen stuff like <code>c0b656b1-7351-4dc2-84c8-62a2afb41e66</code> somewhere. This is a UUID (or <em>Universally Unique IDentifier</em>).</p>
<p>Which is nice. UUIDs are guaranteed to be <em>Universally Unique</em>, which makes them good candidates for primary keys (and neatly solve the issue of having primary keys non unique across tables).</p>
<p>More precisely, UUIDs are 128 bits values, with textual representation in hex digits. It bears repeating, because many people think that UUIDs are stored as text.</p>
<h4 id="uuids-are-128-bit-values">UUIDs are 128 bit values</h4>
<p>There are different versions of UUIDs, based on how they&#39;re created. Within the 128 bits, 4 are used to encode the version. The kind we&#39;re interested in is UUIDv4, which is based on randomness.</p>
<h4 id="uuidv4-are-perfectly-well-indexed-by-postgresql">UUIDv4 are perfectly well indexed by PostgreSQL</h4>
<h4 id="uuidv4-values-are-random">UUIDv4 values are random</h4>
<p>UUIDv4 values being random, you don&#39;t have a guaranteed uniqueness. However, the probability of a collision is rather small (see <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions">Random UUID probability of duplicates</a>).</p>
<p>Also, keep in mind that in the extremely unlikely case (you&#39;re more likely to get hit by a meteorite) of colliding UUIDs, it will be caught by the DB thanks to the primary key constraint.</p>
<p>UUIDv4 adds two reserved bits to the already used ones, so we&#39;re left with 122 bits of information.</p>
<pre><code class="language-text">λ&gt; 2 ^ 122
5316911983139663491615228241121378304
</code></pre>
<p>This should be enough for your needs.</p>
<p>The fact that UUIDv4 values are random gives us interesting properties:</p>
<ul>
<li>you can&#39;t enumerate values</li>
<li>you don&#39;t know how many values are present in each table</li>
<li>you don&#39;t have to talk to the database to construct a value</li>
</ul>
<p>The two first properties are nice, scroll up if you don&#39;t remember why. The third one deserves some extra explanations.</p>
<p>Sequences are mutable state, you need atomicity on get-and-increment, to preserve uniqueness. So everytime you need to insert an entity, you need the DB to give you its primary key. The entities in your code are incomplete until you talk to the DB. Since a sequential key is technical, not semantic, this can usually be handled by your ORM (or data mapper, ORMs are bad, m&#39;kay?). When inserting several related entities, this can cause additional problems, because you&#39;re not only lacking the primary keys, but also the foreign keys too, which are semantic, not just technical.</p>
<p>The UUIDv4 generation algorithm is well documented and available virtually anywhere, so you can generate whole entities without ever talking to the database. This makes the code simpler and clearer as you don&#39;t have to handle partially-created entities, and you can test your entity-generation code without having to talk to a <strong>giant blob of mutable state over the network</strong>.</p>
<p>Also, <code>serial</code> is a 32 bit integer. You&#39;ll reach overflow at some point. Debugging it and migrating a production database to 64 bit integers is an interesting experience, but maybe you can take my word for it and avoid it altogether. With UUIDs it&#39;s a problem you just don&#39;t have.</p>
<p>Also, if you&#39;re brave enough to run a SQL database in a multi-master setup (please, please, please, DON&#39;T), then you&#39;re relieved from the shenanigans of having conflict avoiding sequence generation. But please don&#39;t run SQL databases in multi-master setups. I have done that: one star, would not recommend.</p>
<h3 id="uuids-in-postgresql">UUIDs in PostgreSQL</h3>
<p>PostgreSQL supports UUIDs, through the type <code>uuid</code>.</p>
<pre><code class="language-sql">&gt; select &#39;697dffc9-8ba5-410c-b677-227475a73530&#39;::uuid;
uuid                 
--------------------------------------
    697dffc9-8ba5-410c-b677-227475a73530
(1 row)
</code></pre>
<p>By default PostgreSQL doesn&#39;t have the ability to generate UUIDv4 values. You need the <code>uuid-ossp</code> extension for that. From <code>9.4</code>, UUIDv4 generation is also provided by the <code>pgcrypto</code> extension.</p>
<pre><code class="language-sql">CREATE EXTENSION &quot;uuid-ossp&quot;;
-- or CREATE EXTENSION &quot;pgcrypto&quot;;
create table entity(
  entity_id uuid primary key default uuid_generate_v4(),
  -- or entity_id uuid primary key default gen_random_uuid(),
  attribute text not null
);
</code></pre>
<pre><code class="language-sql">&gt; insert into entity (attribute) values (&#39;toto&#39;);
INSERT 0 1
&gt; table entity;
                entity_id               | attribute 
--------------------------------------+-----------
    b2a3d43b-5b81-4127-be29-d849de607d78 | toto
(1 row)
</code></pre>
<p>You can use UUIDs without the <code>uuid-ossp</code> extension, but you will have to provide UUIDs when inserting entities (which is a good thing to do anyway).</p>
<h3 id="when-uuids-are-not-what-you-need">When UUIDs are not what you need</h3>
<p>If you don&#39;t have mutable state, then you don&#39;t need a technical primary key, and you can use a semantic key.</p>
<p>If you have strong storage constraints, UUIDs can cause a problem, since they use 2 to 4 times as many space as a serial or big serial. So if you have strong size constraints <strong>and if you don&#39;t expose the primary keys</strong>, then UUIDs may be overkill. Also, UUIDs being random, you lose locality, and your index ends up scattered. This causes a definite performance hit when confronted to high insert rates. Also, this creates extra disk use.</p>
<p>In my experience, UUIDs are a safe default. You can question it when you have strong performance constraints and a safe environment.</p>
<h3 id="how-to-generate-uuids-in-language">How to generate UUIDs in $LANGUAGE</h3>
<h4 id="java-scala">Java, Scala</h4>
<p>It&#39;s in the standard library.</p>
<pre><code class="language-java">java.util.UUID.randomUUID
</code></pre>
<h4 id="nodejs">Node.js</h4>
<pre><code class="language-bash">npm install uuid
</code></pre>
<pre><code class="language-javascript">var uuid = require(&quot;uuid&quot;);

uuid.v4();
</code></pre>
<h4 id="php">PHP</h4>
<p>Install <code>ramsey/uuid</code> from composer.</p>
<pre><code class="language-php">$uuid4 = Uuid::uuid4();
</code></pre>
<h4 id="haskell">Haskell</h4>
<p>Install <code>uuid</code> from hackage</p>
<pre><code class="language-haskell">uuid :: IO UUID
uuid = nextRandom
</code></pre>
]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2020/12/primary-key-type-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="primary key type 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2020/12/primary-key-type-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2020/12/primary-key-type-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2020/12/primary-key-type-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2020/12/primary-key-type-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2020/12/primary-key-type-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>As big users of PostgreSQL, we had the opportunity of re-thinking the idioms common in the world of relational DBs.</p>
<p>Today, I&#39;ll talk about why we stopped using serial integers for our primary keys, and why we&#39;re now extensively using Universally Unique IDs (or UUIDs) almost everywhere.</p>
<h3 id="tldr">TL;DR</h3>
<p>Use UUIDs as primary keys. They can be freely exposed without disclosing sensitive information, they are not predictable and they are performant.</p>
<span id="more-2799"></span>

<h3 id="primary-keys-technical-keys-and-semantic-keys">Primary keys, technical keys and semantic keys</h3>
<p>A relational database is a graph where nodes are called entities and edges relations. To be able to express a relation between entities, we need to be able to uniquely refer to any entity: that&#39;s the role of a primary key.</p>
<p>The role of a primary key is to provide a stable, indexable reference to an entity. You have two ways to construct your primary key: either as a <em>semantic</em> key, or as a <em>technical</em> key.</p>
<p>A <em>semantic</em> primary key is extracted from the entities attributes (ie you use one or several fields of your entity as its primary key).</p>
<p>A <em>technical</em> primary key is completely unrelated to the fields of its entity. It&#39;s constructed when the entity is inserted in the DB.</p>
<p>Ideally, semantic keys would be better, as it allows for a very simple way to understand and compare entities. But relational DBs are built upon a fundamentally mutable model. The current state of the world is stored in the database, and entities are subject to mutation. Relational DBs are <strong>very</strong> good at storing a <em>relatively</em> small amount of data, and are not well suited for immutable databases.</p>
<p>That&#39;s why to be able to have <strong>stable</strong> primary keys, we commonly resort to <em>serial IDs</em>. Serial IDs are a technical key, as they&#39;re not related to the actual contents of its entity.</p>
<p>To be fair, you can configure your foreign key to have <code>ON UPDATE CASCADE</code> to have primary key updates automatically propagated everywhere within the database, but it doesn&#39;t solve the problem if you&#39;ve exposed primary key values outside the DB.</p>
<h4 id="whats-a-serial-id">What&#39;s a serial ID?</h4>
<p>Basically, a serial id is a number that increases everytime you insert a row. The database does the bookkeeping for you, so it&#39;s transparent for the developer.</p>
<pre><code class="language-sql">create table entity(
  entity_id serial primary key,
  attribute text not null
);
</code></pre>
<p>We can then insert values in the table; postgres will handle the <code>entity_id</code> field.</p>
<pre><code class="language-sql">&gt; insert into entity (attribute) values (&#39;ohai&#39;);
INSERT 0 1

&gt; select * from entity;
    entity_id | attribute 
-----------+-----------
            1 | ohai
(1 row)
</code></pre>
<p>The row has been inserted, and the entity has an automatically attributed id. In postgresql, <code>serial</code> is implemented through a <em>sequence</em>, which acts a bit like a counter. We can inspect its current state:</p>
<pre><code class="language-sql">&gt; select currval(&#39;entity_entity_id_seq&#39;::regclass);
currval 
---------
        1
(1 row)
</code></pre>
<p>OK, so we have a perfectly good primary key for our entities. What&#39;s the problem?</p>
<h3 id="why-serial-ids-can-be-a-problem">Why serial IDs can be a problem</h3>
<h4 id="information-disclosure">Information disclosure</h4>
<p>The current value corresponds to the last value used as a primary key. Since the sequence starts at 1 and is incremented 1 by 1, <code>currval</code> roughly corresponds in our case to the number of rows in the table (not exactly, because of deletions).</p>
<p>So, if you want to count the number of rows in a given table, all you have to do is to have the system generate a new entity and inspect its ID.</p>
<p>So, do users have access to primary keys? The answer is often yes: primary keys are very often exposed to the user, most often in URLs, as we want URLs to be stable (see <a href="http://www.w3.org/Provider/Style/URI.html">cool URIs don&#39;t change</a>).</p>
<p>Let&#39;s say you&#39;re a company operating a SaaS, <strong>all it takes to know your user count is to create an account</strong>. A number of social networks boasting impressive user bases were pwn3d this way. Just by creating an account and looking at a link.</p>
<h4 id="entity-enumerations">Entity enumerations</h4>
<p>An even bigger problem is that it&#39;s very easy to enumerate the entities in any given table. You start from 1, and you keep on incrementing the value. It becomes very easy to scrape all your entities. It leads to spamming (just don&#39;t start from 1, as you don&#39;t want to spam the admin team ;-) ), or worse. If you have light access control, only based on the knowledge of a given URL, then anybody can display private information.</p>
<h4 id="non-uniqueness-across-tables">Non uniqueness across tables</h4>
<p>Since each table has its own sequence, an identical value will be found as the primary key of different entities. Now imagine you make a tab-completed typo when deleting a row. Yeah, you&#39;ve just deleted an arbitrary row somewhere in your DB. Let&#39;s hope you don&#39;t have too many <code>ON DELETE CASCADE</code> configured.</p>
<h3 id="workarounds">Workarounds</h3>
<p>You can configure your sequence to start at an arbitrary point, have an increment bigger than one, or even share the sequence between tables. In any case, you&#39;re still disclosing information about your growth, and you&#39;ll just reach integer overflow quicker. Not really a perfect solution.</p>
<h3 id="a-word-on-uuids">A word on UUIDs</h3>
<p>You may already have seen stuff like <code>c0b656b1-7351-4dc2-84c8-62a2afb41e66</code> somewhere. This is a UUID (or <em>Universally Unique IDentifier</em>).</p>
<p>Which is nice. UUIDs are guaranteed to be <em>Universally Unique</em>, which makes them good candidates for primary keys (and neatly solve the issue of having primary keys non unique across tables).</p>
<p>More precisely, UUIDs are 128 bits values, with textual representation in hex digits. It bears repeating, because many people think that UUIDs are stored as text.</p>
<h4 id="uuids-are-128-bit-values">UUIDs are 128 bit values</h4>
<p>There are different versions of UUIDs, based on how they&#39;re created. Within the 128 bits, 4 are used to encode the version. The kind we&#39;re interested in is UUIDv4, which is based on randomness.</p>
<h4 id="uuidv4-are-perfectly-well-indexed-by-postgresql">UUIDv4 are perfectly well indexed by PostgreSQL</h4>
<h4 id="uuidv4-values-are-random">UUIDv4 values are random</h4>
<p>UUIDv4 values being random, you don&#39;t have a guaranteed uniqueness. However, the probability of a collision is rather small (see <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions">Random UUID probability of duplicates</a>).</p>
<p>Also, keep in mind that in the extremely unlikely case (you&#39;re more likely to get hit by a meteorite) of colliding UUIDs, it will be caught by the DB thanks to the primary key constraint.</p>
<p>UUIDv4 adds two reserved bits to the already used ones, so we&#39;re left with 122 bits of information.</p>
<pre><code class="language-text">λ&gt; 2 ^ 122
5316911983139663491615228241121378304
</code></pre>
<p>This should be enough for your needs.</p>
<p>The fact that UUIDv4 values are random gives us interesting properties:</p>
<ul>
<li>you can&#39;t enumerate values</li>
<li>you don&#39;t know how many values are present in each table</li>
<li>you don&#39;t have to talk to the database to construct a value</li>
</ul>
<p>The two first properties are nice, scroll up if you don&#39;t remember why. The third one deserves some extra explanations.</p>
<p>Sequences are mutable state, you need atomicity on get-and-increment, to preserve uniqueness. So everytime you need to insert an entity, you need the DB to give you its primary key. The entities in your code are incomplete until you talk to the DB. Since a sequential key is technical, not semantic, this can usually be handled by your ORM (or data mapper, ORMs are bad, m&#39;kay?). When inserting several related entities, this can cause additional problems, because you&#39;re not only lacking the primary keys, but also the foreign keys too, which are semantic, not just technical.</p>
<p>The UUIDv4 generation algorithm is well documented and available virtually anywhere, so you can generate whole entities without ever talking to the database. This makes the code simpler and clearer as you don&#39;t have to handle partially-created entities, and you can test your entity-generation code without having to talk to a <strong>giant blob of mutable state over the network</strong>.</p>
<p>Also, <code>serial</code> is a 32 bit integer. You&#39;ll reach overflow at some point. Debugging it and migrating a production database to 64 bit integers is an interesting experience, but maybe you can take my word for it and avoid it altogether. With UUIDs it&#39;s a problem you just don&#39;t have.</p>
<p>Also, if you&#39;re brave enough to run a SQL database in a multi-master setup (please, please, please, DON&#39;T), then you&#39;re relieved from the shenanigans of having conflict avoiding sequence generation. But please don&#39;t run SQL databases in multi-master setups. I have done that: one star, would not recommend.</p>
<h3 id="uuids-in-postgresql">UUIDs in PostgreSQL</h3>
<p>PostgreSQL supports UUIDs, through the type <code>uuid</code>.</p>
<pre><code class="language-sql">&gt; select &#39;697dffc9-8ba5-410c-b677-227475a73530&#39;::uuid;
uuid                 
--------------------------------------
    697dffc9-8ba5-410c-b677-227475a73530
(1 row)
</code></pre>
<p>By default PostgreSQL doesn&#39;t have the ability to generate UUIDv4 values. You need the <code>uuid-ossp</code> extension for that. From <code>9.4</code>, UUIDv4 generation is also provided by the <code>pgcrypto</code> extension.</p>
<pre><code class="language-sql">CREATE EXTENSION &quot;uuid-ossp&quot;;
-- or CREATE EXTENSION &quot;pgcrypto&quot;;
create table entity(
  entity_id uuid primary key default uuid_generate_v4(),
  -- or entity_id uuid primary key default gen_random_uuid(),
  attribute text not null
);
</code></pre>
<pre><code class="language-sql">&gt; insert into entity (attribute) values (&#39;toto&#39;);
INSERT 0 1
&gt; table entity;
                entity_id               | attribute 
--------------------------------------+-----------
    b2a3d43b-5b81-4127-be29-d849de607d78 | toto
(1 row)
</code></pre>
<p>You can use UUIDs without the <code>uuid-ossp</code> extension, but you will have to provide UUIDs when inserting entities (which is a good thing to do anyway).</p>
<h3 id="when-uuids-are-not-what-you-need">When UUIDs are not what you need</h3>
<p>If you don&#39;t have mutable state, then you don&#39;t need a technical primary key, and you can use a semantic key.</p>
<p>If you have strong storage constraints, UUIDs can cause a problem, since they use 2 to 4 times as many space as a serial or big serial. So if you have strong size constraints <strong>and if you don&#39;t expose the primary keys</strong>, then UUIDs may be overkill. Also, UUIDs being random, you lose locality, and your index ends up scattered. This causes a definite performance hit when confronted to high insert rates. Also, this creates extra disk use.</p>
<p>In my experience, UUIDs are a safe default. You can question it when you have strong performance constraints and a safe environment.</p>
<h3 id="how-to-generate-uuids-in-language">How to generate UUIDs in $LANGUAGE</h3>
<h4 id="java-scala">Java, Scala</h4>
<p>It&#39;s in the standard library.</p>
<pre><code class="language-java">java.util.UUID.randomUUID
</code></pre>
<h4 id="nodejs">Node.js</h4>
<pre><code class="language-bash">npm install uuid
</code></pre>
<pre><code class="language-javascript">var uuid = require(&quot;uuid&quot;);

uuid.v4();
</code></pre>
<h4 id="php">PHP</h4>
<p>Install <code>ramsey/uuid</code> from composer.</p>
<pre><code class="language-php">$uuid4 = Uuid::uuid4();
</code></pre>
<h4 id="haskell">Haskell</h4>
<p>Install <code>uuid</code> from hackage</p>
<pre><code class="language-haskell">uuid :: IO UUID
uuid = nextRandom
</code></pre>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Lambdacon 2015</title>
		<link>https://www.clever.cloud/blog/company/2015/04/07/lambdacon/</link>
		
		<dc:creator><![CDATA[Clement Delafargue]]></dc:creator>
		<pubDate>Tue, 07 Apr 2015 14:12:00 +0000</pubDate>
				<category><![CDATA[Company]]></category>
		<category><![CDATA[Engineering]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[Scala]]></category>
		<guid isPermaLink="false">https://www2.cleverapps.io/wp/blog/technology/2015/04/07/lambdacon/</guid>

					<description><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/lambdacon-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="lambdacon 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/lambdacon-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/lambdacon-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/lambdacon-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/lambdacon-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/lambdacon-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>Here at Clever Cloud, we&#39;re enthusiastic users of functional programming. It helps us a lot when it comes to have clean and maintainable code.</p>
<p>That&#39;s why we were delighted to fly to Bologna for the LambdaCon, to meet the Italian FP community as well as some twitter friends.</p>
<span id="more-2742"></span>

<p>After a stop at Yoox offices where Quentin and I got the opportunity to have a chat with developers and the other speakers, it was time for the actual conference.</p>
<h2 id="fun-with-categories">Fun with Categories</h2>
<p>Many interesting functional programming concepts come directly from a branch of mathematics called Category Theory. The keynote speaker <a href="https://twitter.com/bartoszmilewski">Bartosz Milewski</a> went as far as saying that CT is the next revolution after mainstream FP adoption.</p>
<p>I was surprised to witness that &quot;Kleisli Category&quot; frightened people less than the dreaded M-word.</p>
<p>Category Theory is a vast field and can be intimidating for newcomers due to its extremely high level of abstraction, but the good news is that Bartosz is writing an introduction book aimed at developers.</p>
<h2 id="dissecting-the-rabbit">Dissecting the rabbit</h2>
<p>Since we use RabbitMQ a lot at Clever Cloud, we were happy to be able to attend <a href="https://twitter.com/old_sound">Alvaro Videla</a>&#39;s talk about RabbitMQ&#39;s internals, especially the actor hierarchy in place inside RabbitMQ.</p>
<h2 id="streams-on-top-of-scala">Streams on top of Scala</h2>
<p>We&#39;re big users of Scala and we deal with a lot of streamed data. That&#39;s why we&#39;ve been using Scala&#39;s streaming libraries a lot, first with Play&#39;s iteratees, then with scalaz-streams and akka-streams.</p>
<p>Quentin did a nice round-up of what&#39;s available and the different use cases for streaming libs in Scala.</p>
<p>The slides are available on slideshare: 
<a href="http://www.slideshare.net/quentinadam/streams-on-top-of-scala-lambdacon">Streams on top of Scala</a></p>
<h2 id="tdd-as-in-type-directed-development">TDD as in Type-Directed Development</h2>
<p>Even though I&#39;ve started my career with dynamicallly typed languages, I&#39;ve been very happy with static, expressive type systems these last years. In this talk I showed how to use types not only for safety, but as a very powerful design and communication tool.</p>
<p>You can have a look at the slides: <a href="https://clementd-files.cellar.services.clever-cloud.com/blog/typedd-lambdacon.html">TDD, as in Type-Directed Development</a></p>
<h2 id="the-european-fp-community-is-great">The european FP community is great</h2>
<p>The people from CodersTug did a great job for their first conference. And it&#39;s great to see such forward-thinking events take place in Europe.</p>
<p><a href="https://twitter.com/Dorvaryn/status/581873184909238273"><img src="https://www2.cleverapps.io/app/uploads/2021/08/lambdacon-speakers.jpg" alt=""></a></p>
]]></description>
										<content:encoded><![CDATA[<p><img width="1400" height="540" src="https://cdn.clever-cloud.com/uploads/2021/08/lambdacon-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="lambdacon 1" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2021/08/lambdacon-1.jpg 1400w, https://cdn.clever-cloud.com/uploads/2021/08/lambdacon-1-300x116.jpg 300w, https://cdn.clever-cloud.com/uploads/2021/08/lambdacon-1-1024x395.jpg 1024w, https://cdn.clever-cloud.com/uploads/2021/08/lambdacon-1-768x296.jpg 768w, https://cdn.clever-cloud.com/uploads/2021/08/lambdacon-1-1368x528.jpg 1368w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></p><p>Here at Clever Cloud, we&#39;re enthusiastic users of functional programming. It helps us a lot when it comes to have clean and maintainable code.</p>
<p>That&#39;s why we were delighted to fly to Bologna for the LambdaCon, to meet the Italian FP community as well as some twitter friends.</p>
<span id="more-2742"></span>

<p>After a stop at Yoox offices where Quentin and I got the opportunity to have a chat with developers and the other speakers, it was time for the actual conference.</p>
<h2 id="fun-with-categories">Fun with Categories</h2>
<p>Many interesting functional programming concepts come directly from a branch of mathematics called Category Theory. The keynote speaker <a href="https://twitter.com/bartoszmilewski">Bartosz Milewski</a> went as far as saying that CT is the next revolution after mainstream FP adoption.</p>
<p>I was surprised to witness that &quot;Kleisli Category&quot; frightened people less than the dreaded M-word.</p>
<p>Category Theory is a vast field and can be intimidating for newcomers due to its extremely high level of abstraction, but the good news is that Bartosz is writing an introduction book aimed at developers.</p>
<h2 id="dissecting-the-rabbit">Dissecting the rabbit</h2>
<p>Since we use RabbitMQ a lot at Clever Cloud, we were happy to be able to attend <a href="https://twitter.com/old_sound">Alvaro Videla</a>&#39;s talk about RabbitMQ&#39;s internals, especially the actor hierarchy in place inside RabbitMQ.</p>
<h2 id="streams-on-top-of-scala">Streams on top of Scala</h2>
<p>We&#39;re big users of Scala and we deal with a lot of streamed data. That&#39;s why we&#39;ve been using Scala&#39;s streaming libraries a lot, first with Play&#39;s iteratees, then with scalaz-streams and akka-streams.</p>
<p>Quentin did a nice round-up of what&#39;s available and the different use cases for streaming libs in Scala.</p>
<p>The slides are available on slideshare: 
<a href="http://www.slideshare.net/quentinadam/streams-on-top-of-scala-lambdacon">Streams on top of Scala</a></p>
<h2 id="tdd-as-in-type-directed-development">TDD as in Type-Directed Development</h2>
<p>Even though I&#39;ve started my career with dynamicallly typed languages, I&#39;ve been very happy with static, expressive type systems these last years. In this talk I showed how to use types not only for safety, but as a very powerful design and communication tool.</p>
<p>You can have a look at the slides: <a href="https://clementd-files.cellar.services.clever-cloud.com/blog/typedd-lambdacon.html">TDD, as in Type-Directed Development</a></p>
<h2 id="the-european-fp-community-is-great">The european FP community is great</h2>
<p>The people from CodersTug did a great job for their first conference. And it&#39;s great to see such forward-thinking events take place in Europe.</p>
<p><a href="https://twitter.com/Dorvaryn/status/581873184909238273"><img src="https://www2.cleverapps.io/app/uploads/2021/08/lambdacon-speakers.jpg" alt=""></a></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
