<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[The Stickman Blog]]></title><description><![CDATA[Gideon Wanjohi articles]]></description><link>https://blog.stickmancorp.com</link><generator>RSS for Node</generator><lastBuildDate>Tue, 05 May 2026 06:51:32 GMT</lastBuildDate><atom:link href="https://blog.stickmancorp.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Write your first RESTful API in FastAPI]]></title><description><![CDATA[A REST API is an API that conforms to the constrains of REST architecture and style. REST stands for representational state transfer. It was created by Roy Fielding. The cool thing about REST APIs is that they're cacheable, stateless and consistent. ...]]></description><link>https://blog.stickmancorp.com/write-your-first-restful-api-in-fastapi</link><guid isPermaLink="true">https://blog.stickmancorp.com/write-your-first-restful-api-in-fastapi</guid><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Python]]></category><category><![CDATA[APIs]]></category><category><![CDATA[REST API]]></category><category><![CDATA[Web API]]></category><dc:creator><![CDATA[Gideon Wanjohi]]></dc:creator><pubDate>Sun, 01 Aug 2021 12:05:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1627819466200/2Q7aIHKJs.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A REST API is an API that conforms to the constrains of REST architecture and style. REST stands for representational state transfer. It was created by Roy Fielding. The cool thing about REST APIs is that they're cacheable, stateless and consistent. You can read more about it <a target="_blank" href="https://www.redhat.com/en/topics/api/what-is-a-rest-api">here</a>.
A simple way to look at an API is viewing it as an interpreter between the computer resources, or web services and a client, or user. It's also a way for organizations to share information securely. Say you want to get the ten most rated movies from IMDB. IMDB can share this information to you through an API, without disclosing sensitive information. Check out the <a target="_blank" href="https://imdb-api.com/api">imdb API</a>.</p>
<p>Today we'll  use FastAPI framework to build our first web API. <a target="_blank" href="https://fastapi.tiangolo.com">FastAPI</a> is written in Python, and is just one of the python web frameworks. Two of the more known python frameworks would be <a target="_blank" href="https://www.djangoproject.com">Django</a> and <a target="_blank" href="https://flask.palletsprojects.com">Flask</a>.</p>
<p>Let's get to it!</p>
<p>What we'll cover: <br /></p>
<ul>
<li><a class="post-section-overview" href="#pre">Prerequisites</a> <br /></li>
<li><a class="post-section-overview" href="#intro">What is FastAPI?</a> <br /></li>
<li><a class="post-section-overview" href="#hello">Hello World in FastAPI</a> <br /></li>
<li><a class="post-section-overview" href="#basics">FastAPI basics</a> <br /></li>
<li><a class="post-section-overview" href="#code">Build a working API</a> <br /></li>
<li><a class="post-section-overview" href="#swagger">Swagger UI</a> <br /></li>
</ul>
<h4 id="lessdiv-idpregreaterprerequisiteslessdivgreater"><div id="pre">Prerequisites</div></h4>
<p>If you just want to read, then you can just follow along.
If you want to code along, here's what we're going to need:</p>
<ul>
<li><a target="_blank" href="https://www.python.org/">Python</a> installed on your machine. If you're on linux, it's already installed :)</li>
<li>A virtual environment. It's not required, but it's good practice. Run the following command to install:<br />
<div id="virtual"></div><pre><code class="lang-bash">sudo apt install python3-pip &amp;&amp; sudo pip3 install virtualenv
</code></pre>
<ul>
<li>A code editor. I'm using VS Code. You can download it <a target="_blank" href="https://code.visualstudio.com/download">here</a>. You'll need the python extension for more productivity. Just click on the Extensions &gt; Search 'Python', and ensure you install the Microsoft's version.</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627808056692/HXbWHffTv.png" alt="image.png" /></p>
<h4 id="lessdiv-idintrogreaterwhat-is-fastapilessdivgreater"><div id="intro">What is FastAPI?</div></h4>
<p>FastAPI is a high performance, easy to learn, fast to code, ready for production python framework.
It first showed up in 2019, created by Sebastian Ramírez. It improves the deveoper experience by having self-documenting APIs, and at the same time reduces boilerpate code.</p>
<h4 id="lessdiv-idhellogreaterhello-world-in-fastapilessdivgreater"><div id="hello">Hello World in FastAPI</div></h4>
<p>Let's see how easy it is to use FastAPI: </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627809777899/L1FaYd2rC.png" alt="image.png" /></p>
<p>Here's what I've done: <br /></p>
<ol>
<li><code>from fastapi import FastAPI</code> imports the FastAPI </li>
<li><code>app = FastAPI()</code> creates an instance of fastapi for us to use</li>
<li><code>@app.get("/")</code> is a decorator that uses the http get method from FastAPI.</li>
<li><code>def index()</code> &lt;- Here we define a method that returns a hello world message 
<br /></li>
</ol>
<h4 id="lessdiv-idbasicsgreaterfastapi-basicslessdivgreater"><div id="basics">FastAPI basics</div></h4>
<p>Most important things to understand while working with FastAPI: <br /></p>
<ul>
<li>Typehints</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627815614158/ivEQuwlgR.png" alt="image.png" />
Although typehints are built into python, they're crucial when working with FastAPI. As you can see in the example above, you will need to explicitely define the data type for all your variables ie: <code>name: str</code>. This will apply for all data types say <code>str</code>, <code>int</code>, <code>list</code>, <code>dict</code> etc.</p>
<ul>
<li>Path and Path Parameters</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627810061715/qaJ8yEbc-.png" alt="image.png" />
The <code>"/books"</code> inside the parenthesis is a path. This means that when user goes to the path say example.com/books, they will be accessing this "/books" resource path</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627810185491/VBBu4Mo0Z.png" alt="image.png" />
The <code>"{book_id}"</code> is called a path parameter. Path parameters are enclosed inside of  curly braces <code>{}</code>. They offer a way to control specific resources. Say for instance you want to get a specific book, then you might want to add a path parameter with that book's id.</p>
<ul>
<li><p>Query Parameters
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627810829358/4XVf728uo.png" alt="image.png" />
These are not required. All parameters outside of the path are considered as query parameters.
Note the <code>start: int</code> and <code>end: int</code> on the <code>all_read_books</code> function. Those are the two query parameters that our API will expect.
The query is represented in a key-value pair, comes after a question mark <code>?</code> and is separated by an ampersand <code>&amp;</code>.
In our case, the query would be something similar to <code>https://example.com/books/?start=0&amp;end=12</code></p>
</li>
<li><p>Request Body
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627811486909/uCBdbb35T.png" alt="image.png" /></p>
</li>
</ul>
<p>A request body is what the client will send to our API.
In our example, we've created a <code>Book</code> class, and parsed it to the <code>add_a_book</code> function as a <code>book</code> parameter. This will send an instance of a <code>Book</code> with the post method to our API.</p>
<h4 id="lessdiv-idcodegreaterbuild-a-working-apilessdivgreater"><div id="code">Build a working API</div></h4>
<p>Now let's build a working API in FastAPI: <br /></p>
<ul>
<li>Create an empty directory anywhere: <pre><code class="lang-bash">mkdir fastapi &amp;&amp; <span class="hljs-built_in">cd</span> fastapi
</code></pre>
</li>
<li>Create a virtual environment and activate it:<pre><code class="lang-bash">virtualenv venv &amp;&amp; <span class="hljs-built_in">source</span> venv/bin/activate
</code></pre>
</li>
<li>Install FastAPI: <pre><code class="lang-bash">pip install fastapi uvicorn
</code></pre>
</li>
<li><p>Now open the in your editor:</p>
<pre><code class="lang-bash">code .
</code></pre>
</li>
<li><p>Let's write our first endpoint! 
 Get all books.
Copy the code below:</p>
</li>
</ul>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> fastapi <span class="hljs-keyword">import</span> FastAPI

app = FastAPI()

db = []

<span class="hljs-meta">@app.get("/books")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_all_books</span>():</span>
    <span class="hljs-keyword">return</span> db
</code></pre>
<p>Line 3 creates an empty list to act as our in-memory data storage. the <code>/books</code> path will return whatever is inside the db. Save the file as <code>main.py</code> (This is important)</p>
<ul>
<li>To view it, go back to the terminal window and run the following command:<pre><code class="lang-bash">uvicorn main:app --reload
</code></pre>
</li>
</ul>
<p>This calls the <code>app</code> variable inside of the <code>main.py</code> script. The <code>--reload</code> ensures that the server will refresh each time we save the file.
Now head over to <a target="_blank" href="http://localhost:8000/books">localhost:8000/books</a></p>
<p>You should see something similar to this: <br /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627813304505/D09BGFcTi.png" alt="image.png" /></p>
<ul>
<li>Add a book to our <code>db</code>: <br /></li>
</ul>
<p>First we'll need a <code>Book</code>. For that, we'll create a <code>Book</code> class to act as our Response Model. Import <code>BaseModel</code>:<br /></p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> pydantic <span class="hljs-keyword">import</span> BaseModel
</code></pre>
<p>Add the <code>Book</code> class and <code>add_a_book</code> function: <br /></p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Book</span>(<span class="hljs-params">BaseModel</span>):</span>
    title: str

<span class="hljs-meta">@app.post("/books")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_a_book</span>(<span class="hljs-params">book: Book</span>):</span>
    <span class="hljs-keyword">return</span> db.append(book)
</code></pre>
<p>Here, we send the <code>book</code> request (Our book <code>title</code>) to the API.</p>
<ul>
<li>Delete a <code>Book</code> from <code>db</code>: <br />
To delete a book, we'll just use an ordinary pop() method <br />
Notice we're using <code>book_id</code> as a path parameter: </li>
</ul>
<pre><code class="lang-python"><span class="hljs-meta">@app.delete("/books/{book_id}")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">delete_a_book</span>(<span class="hljs-params">book_id: int</span>):</span>
    <span class="hljs-keyword">return</span> db.pop(book_id)
</code></pre>
<ul>
<li>Get a specific <code>Book</code>
To get one book, we'll need the <code>book</code>'s id on the list. Here's how to do it:</li>
</ul>
<pre><code class="lang-python">
<span class="hljs-meta">@app.get("/books/{book_id}")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_a_book</span>(<span class="hljs-params">book_id: int</span>):</span>
    <span class="hljs-keyword">return</span> db[book_id]
</code></pre>
<p>Here we use the list index as our <code>book_id</code> and parse it as our path parameter.</p>
<p>Get entire code on my <a target="_blank" href="https://github.com/waWanjohi/fastapi-demo">Github</a> or <a target="_blank" href="https://bitbucket.org/gekthee/fastapi-demo/">BitBucket</a> repo.</p>
<h4 id="lessdiv-idswaggergreaterswagger-uilessdivgreater"><div id="swagger">Swagger UI</div></h4>
<p>To test out our API, we'll use the inbuilt documentation for FastAPI.
Head over to your browser and open the link <a target="_blank" href="http://localhost:8000/docs">http://localhost:8000/docs</a>. You should be greeted by this page: </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627817228787/IPUVp4cbr.png" alt="image.png" /></p>
<p>Let's test the methods:</p>
<ul>
<li><p>Expand <code>Get All Books</code>, click <code>try it out</code> then <code>Excecute</code>:
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627818720604/ZCQOAM5EU.png" alt="image.png" /></p>
</li>
<li><p>We'll do the same for <code>Add A Book</code>:
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627818790652/0M_5uD77W.png" alt="image.png" />
Add several books so that we have something to test with. As you can see, I've added four:</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627818266033/DM83Ai9UV.png" alt="image.png" /></p>
<ul>
<li><code>Get A Book</code>, it requires us to enter a <code>book_id</code>, and returns a book in that index in our <code>db</code></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627818564863/5SoH1M-d7.png" alt="image.png" /></p>
<ul>
<li><code>Delete A Book</code> is similar to <code>Get A Book</code></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627818634030/kuh9jNoxF.png" alt="image.png" /></p>
]]></content:encoded></item></channel></rss>