<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blog on Restish</title><link>https://rest.sh/blog/</link><description>Recent content in Blog on Restish</description><generator>Hugo</generator><language>en-US</language><atom:link href="https://rest.sh/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>Scripting REST APIs Without Fragile curl Loops</title><link>https://rest.sh/blog/scripting-rest-apis-without-fragile-curl-loops/</link><pubDate>Tue, 30 Jun 2026 00:00:00 +0000</pubDate><guid>https://rest.sh/blog/scripting-rest-apis-without-fragile-curl-loops/</guid><description>&lt;p&gt;Somewhere in your infrastructure there is a shell script with a loop like
this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://api.example.com/items?page=1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -n &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$url&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;curl -s &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$url&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$resp&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; jq -r &lt;span class="s1"&gt;&amp;#39;.items[].id&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$resp&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; jq -r &lt;span class="s1"&gt;&amp;#39;.links.next // empty&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It works, mostly. It has also quietly accumulated a list of failure modes that
nobody will notice until a bad day:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;500&lt;/code&gt; response exits with status &lt;code&gt;0&lt;/code&gt;, so the error page flows into &lt;code&gt;jq&lt;/code&gt;,
which prints nothing, and the script &amp;ldquo;succeeds&amp;rdquo; with empty output.&lt;/li&gt;
&lt;li&gt;There is no retry, so one transient network blip fails the whole job — or
worse, half of it.&lt;/li&gt;
&lt;li&gt;There is no timeout, so a hung connection hangs the cron job behind it.&lt;/li&gt;
&lt;li&gt;There is no page bound, so a pagination bug upstream turns the loop into an
accidental load test.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;next&lt;/code&gt; ever points somewhere unexpected — another host, an attacker-
influenced URL in a response body — the loop follows it without a thought.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of these are exotic. They are the standard tax on hand-rolling HTTP
plumbing in shell, paid one incident at a time. This post is about paying it
once, in the tool, instead.&lt;/p&gt;</description></item><item><title>TOON: Token-Efficient API Output for LLM Workflows</title><link>https://rest.sh/blog/toon-token-efficient-api-output-for-llm-workflows/</link><pubDate>Mon, 15 Jun 2026 00:00:00 +0000</pubDate><guid>https://rest.sh/blog/toon-token-efficient-api-output-for-llm-workflows/</guid><description>&lt;p&gt;When a person reads an API response, formatting is free. When an LLM agent
reads one, every character is metered. The response lands in a context window,
the context window is billed by the token, and the format you chose decides how
many tokens the same data costs.&lt;/p&gt;
&lt;p&gt;JSON spends a lot of tokens on that job. A list of one hundred records repeats
every key one hundred times, wraps every string in quotes, and spends tokens on
braces and brackets that a model does not need to understand a table of data.&lt;/p&gt;</description></item><item><title>Turn an OpenAPI Spec Into a CLI Without Generating Code</title><link>https://rest.sh/blog/turn-an-openapi-spec-into-a-cli-without-generating-code/</link><pubDate>Mon, 08 Jun 2026 00:00:00 +0000</pubDate><guid>https://rest.sh/blog/turn-an-openapi-spec-into-a-cli-without-generating-code/</guid><description>&lt;p&gt;OpenAPI is usually treated as an input to something else. Generate an SDK. Render
Swagger UI. Publish reference docs. Feed a contract test. All of those are good
jobs for a spec.&lt;/p&gt;
&lt;p&gt;But there is another useful job hiding in the same document: teach the terminal
how to work with the API.&lt;/p&gt;
&lt;p&gt;That does not have to mean generating a new repository, choosing a language
runtime, publishing a package, and keeping a client binary in sync with every
operation change. A CLI can load an OpenAPI description at runtime, cache what it
needs, and turn repeated API work into commands without making users rebuild a
client.&lt;/p&gt;</description></item><item><title>Restish v2: A CLI for REST APIs, Rebuilt</title><link>https://rest.sh/blog/restish-v2-a-cli-for-rest-apis-rebuilt/</link><pubDate>Sat, 30 May 2026 00:00:00 +0000</pubDate><guid>https://rest.sh/blog/restish-v2-a-cli-for-rest-apis-rebuilt/</guid><description>&lt;p&gt;Most APIs already know more about themselves than the command line does. They
have schemas, auth rules, pagination links, content types, examples, and often a
full OpenAPI description. Then we copy a &lt;code&gt;curl&lt;/code&gt; command into a terminal and
teach all of that context back to the shell one flag at a time.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;curl&lt;/code&gt; is still the universal primitive. Restish is for the moment after that:
when a URL becomes a workflow, and the API should start feeling like a small
native CLI instead of a string you keep rebuilding.&lt;/p&gt;</description></item></channel></rss>