<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jakub Spórna</title>
    <description>The latest articles on DEV Community by Jakub Spórna (@jsporna).</description>
    <link>https://dev.to/jsporna</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F499112%2F239ca4d6-b053-43f1-afe5-5b4e8466c7bf.png</url>
      <title>DEV Community: Jakub Spórna</title>
      <link>https://dev.to/jsporna</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jsporna"/>
    <language>en</language>
    <item>
      <title>Building a Directus API Client for Go</title>
      <dc:creator>Jakub Spórna</dc:creator>
      <pubDate>Mon, 21 Sep 2026 10:17:56 +0000</pubDate>
      <link>https://dev.to/jsporna/building-a-directus-api-client-for-go-2fc1</link>
      <guid>https://dev.to/jsporna/building-a-directus-api-client-for-go-2fc1</guid>
      <description>&lt;p&gt;If you are using &lt;a href="https://directus.io/" rel="noopener noreferrer"&gt;Directus&lt;/a&gt; as a headless CMS or data platform and your application is written in Go, you have probably noticed an interesting gap: Directus has a very capable JavaScript/TypeScript SDK, but the Go ecosystem around it is much smaller.&lt;/p&gt;

&lt;p&gt;That was the motivation behind &lt;strong&gt;&lt;a href="https://github.com/chop-sticks/directus-client-go" rel="noopener noreferrer"&gt;directus-client-go&lt;/a&gt;&lt;/strong&gt;, a typed Go client for the Directus REST API.&lt;/p&gt;

&lt;p&gt;The goal was not to build another thin HTTP wrapper. I wanted something that feels natural to use from Go while staying reasonably close to the API exposed by Directus.&lt;/p&gt;

&lt;h2&gt;
  
  
  The project
&lt;/h2&gt;

&lt;p&gt;The library is available on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/chop-sticks/directus-client-go" rel="noopener noreferrer"&gt;https://github.com/chop-sticks/directus-client-go&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It can be installed directly with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get github.com/chop-sticks/directus-client-go/directus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The project is MIT licensed and is distributed as a standard Go module.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why another Directus client?
&lt;/h2&gt;

&lt;p&gt;Directus exposes a fairly large REST API.&lt;/p&gt;

&lt;p&gt;There are endpoints for items and files, but also users, roles, permissions, policies, flows, operations, dashboards, panels, presets, translations, relations, settings, extensions, collections, fields, authentication, schema management and more.&lt;/p&gt;

&lt;p&gt;A client can therefore become either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a very small wrapper around &lt;code&gt;net/http&lt;/code&gt;, leaving most of the work to the application, or&lt;/li&gt;
&lt;li&gt;a large SDK that tries to model the entire Directus API.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I chose the second direction.&lt;/p&gt;

&lt;p&gt;The library currently mirrors a broad portion of the Directus API command surface, including items, files, folders, users, roles, policies, permissions, flows, operations, panels, dashboards, presets, translations, shares, comments, notifications, activity, revisions, content versions, relations, settings, extensions, collections and fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple example
&lt;/h2&gt;

&lt;p&gt;Getting started is intentionally boring.&lt;/p&gt;

&lt;p&gt;And boring is good for an API client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/chop-sticks/directus-client-go/directus"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"http://localhost:8055"&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"your-static-token"&lt;/span&gt;

    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;directus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;limit&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;

    &lt;span class="n"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"articles"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;directus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Fields&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"author.name"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"status"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s"&gt;"_eq"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"published"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;Sort&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"-date_created"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;Limit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The query structure follows Directus' own query model, including fields, filters, sorting, pagination, search, deep queries, aggregation, grouping, aliases and other query parameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with items
&lt;/h2&gt;

&lt;p&gt;The client exposes the standard CRUD operations you'd expect from a Directus SDK.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;created&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"articles"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"Hello from Go"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"status"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"draft"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;created&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For existing collections, the API follows consistent method conventions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GetXs(q)                 // list
GetX(id, q)              // get one

CreateX(...)             // create one
CreateXs(...)            // create many

PatchX(id, ...)          // update one
PatchXs(keys, ...)       // update by keys
PatchXsBatch(...)        // batch update

DeleteX(id)              // delete one
DeleteXs(keys)           // delete many
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This consistency becomes increasingly useful once you start working with more than one Directus resource.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typed models where they make sense
&lt;/h2&gt;

&lt;p&gt;One of the things I wanted to avoid was forcing everything through &lt;code&gt;map[string]any&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Directus collections are dynamic by design, so arbitrary collections still need a flexible representation.&lt;/p&gt;

&lt;p&gt;But Directus also has core system collections with well-defined schemas.&lt;/p&gt;

&lt;p&gt;For those, the client provides typed models.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetUsersMe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;directus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Fields&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you the flexibility of Directus for user-defined collections while still getting normal Go structs for system resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;

&lt;p&gt;The simplest option is to initialize the client with a static bearer token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;directus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client also supports logging in with Directus credentials and then using the returned access token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"admin@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AccessToken&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it possible to use the same client for applications that rely on a preconfigured token as well as applications that need to authenticate dynamically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing against a real Directus instance
&lt;/h2&gt;

&lt;p&gt;One part of the project that I consider particularly important is the integration test suite.&lt;/p&gt;

&lt;p&gt;Mocking HTTP responses is useful, but it doesn't tell you whether the client actually works with a real Directus installation.&lt;/p&gt;

&lt;p&gt;The repository therefore includes a Docker Compose based integration environment with Directus, PostgreSQL/PostGIS and Redis.&lt;/p&gt;

&lt;p&gt;Integration tests are separated using Go build tags, so the normal test suite remains fast:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;test&lt;/span&gt; ./...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Integration tests can be run with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;task &lt;span class="nb"&gt;test&lt;/span&gt;:integration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--wait&lt;/span&gt;

go &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;integration &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="se"&gt;\&lt;/span&gt;
  ./directus/integration/...

docker compose down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The integration environment can also be configured using &lt;code&gt;DIRECTUS_URL&lt;/code&gt; and &lt;code&gt;DIRECTUS_TOKEN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This gives the project two useful layers of testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             ┌───────────────────────┐
             │     Unit tests        │
             │   fast feedback       │
             └───────────┬───────────┘
                         │
                         ▼
             ┌───────────────────────┐
             │ Integration tests     │
             │ real Directus API     │
             └───────────┬───────────┘
                         │
                         ▼
             ┌───────────────────────┐
             │ Docker Compose stack  │
             │ Directus + DB + Redis │
             └───────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Keeping the development workflow simple
&lt;/h2&gt;

&lt;p&gt;The repository uses &lt;a href="https://taskfile.dev/" rel="noopener noreferrer"&gt;Task&lt;/a&gt; for common development commands.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;task build
task &lt;span class="nb"&gt;test
&lt;/span&gt;task &lt;span class="nb"&gt;test&lt;/span&gt;:cover
task &lt;span class="nb"&gt;test&lt;/span&gt;:race
task lint
task &lt;span class="nb"&gt;fmt
&lt;/span&gt;task vet
task tidy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is also a &lt;code&gt;task ci&lt;/code&gt; command that runs the main quality checks together.&lt;/p&gt;

&lt;p&gt;Documentation and API reference generation are part of the development workflow as well.&lt;/p&gt;

&lt;p&gt;The intention is that contributing to the project should not require remembering a collection of custom commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I want this library to become
&lt;/h2&gt;

&lt;p&gt;The project is still evolving.&lt;/p&gt;

&lt;p&gt;The Directus API is large, and keeping an SDK synchronized with it is an ongoing job rather than something you finish once and put on a shelf.&lt;/p&gt;

&lt;p&gt;The direction I'm aiming for is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;broad coverage of the Directus REST API&lt;/li&gt;
&lt;li&gt;predictable Go naming and method conventions&lt;/li&gt;
&lt;li&gt;typed models for system resources&lt;/li&gt;
&lt;li&gt;flexible support for arbitrary Directus collections&lt;/li&gt;
&lt;li&gt;Directus-compatible query parameters&lt;/li&gt;
&lt;li&gt;good unit-test coverage&lt;/li&gt;
&lt;li&gt;real integration tests against Directus&lt;/li&gt;
&lt;li&gt;documentation that makes extending the client straightforward&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also want the implementation to remain relatively boring internally.&lt;/p&gt;

&lt;p&gt;There is a lot of value in an SDK where adding a new endpoint doesn't require learning an elaborate framework first.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you use Directus and Go
&lt;/h2&gt;

&lt;p&gt;If you're building a Go application around Directus, I'd love for you to give the client a try:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/chop-sticks/directus-client-go" rel="noopener noreferrer"&gt;https://github.com/chop-sticks/directus-client-go&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go package:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://pkg.go.dev/github.com/chop-sticks/directus-client-go" rel="noopener noreferrer"&gt;https://pkg.go.dev/github.com/chop-sticks/directus-client-go&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The package is already published as a Go module, with &lt;code&gt;v1&lt;/code&gt; releases available through the Go module ecosystem.&lt;/p&gt;

&lt;p&gt;Issues, feedback and pull requests are welcome.&lt;/p&gt;

&lt;p&gt;If you're using Directus in a Go project and find a missing endpoint or an API shape that doesn't fit well with the client, that's particularly useful feedback. Those are exactly the kinds of things that help an SDK mature from "works for my project" into something other people can confidently depend on.&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
    </item>
    <item>
      <title>terraform-docs zsh plugin</title>
      <dc:creator>Jakub Spórna</dc:creator>
      <pubDate>Mon, 26 Oct 2020 19:04:48 +0000</pubDate>
      <link>https://dev.to/jsporna/terraform-docs-zsh-plugin-41co</link>
      <guid>https://dev.to/jsporna/terraform-docs-zsh-plugin-41co</guid>
      <description>&lt;p&gt;Working with terraform creating modules I would like to have documentation so I've used &lt;a href="https://github.com/terraform-docs/terraform-docs"&gt;terraform-docs&lt;/a&gt;.&lt;br&gt;
It is tool to generate documentation based on terraform code contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;input variables&lt;/li&gt;
&lt;li&gt;outputs&lt;/li&gt;
&lt;li&gt;providers&lt;/li&gt;
&lt;li&gt;requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usage is very simple:&lt;br&gt;
&lt;code&gt;terraform-docs markdown table . &amp;gt; README.md&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;so you get generated documenation in &lt;em&gt;README.md&lt;/em&gt; file in &lt;em&gt;markdown&lt;/em&gt; format with tables based on &lt;em&gt;.tf&lt;/em&gt; files in current directory.&lt;/p&gt;

&lt;p&gt;I've created &lt;a href="https://en.wikipedia.org/wiki/Z_shell"&gt;zsh&lt;/a&gt; plugin to completation commands and flags. I've decided to share my code in Github:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/jsporna/terraform-docs-zsh-plugin"&gt;https://github.com/jsporna/terraform-docs-zsh-plugin&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;PS&lt;br&gt;
Tool itself contains &lt;em&gt;completetion&lt;/em&gt; command to setup &lt;em&gt;bash&lt;/em&gt; and &lt;em&gt;zsh&lt;/em&gt; but it was added much later than I've created my code.&lt;/p&gt;

</description>
      <category>zsh</category>
      <category>terminal</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
