<?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: Alex John Chamba</title>
    <description>The latest articles on DEV Community by Alex John Chamba (@alexjcm).</description>
    <link>https://dev.to/alexjcm</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F648399%2Fae5eec8f-258f-40c4-9749-f18037e67713.jpg</url>
      <title>DEV Community: Alex John Chamba</title>
      <link>https://dev.to/alexjcm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alexjcm"/>
    <language>en</language>
    <item>
      <title>Generate database documentation with SchemaSpy &amp; Docker (Windows, Linux, macOS)</title>
      <dc:creator>Alex John Chamba</dc:creator>
      <pubDate>Thu, 26 Mar 2026 02:32:07 +0000</pubDate>
      <link>https://dev.to/alexjcm/generate-database-documentation-with-schemaspy-docker-windows-linux-macos-1hn1</link>
      <guid>https://dev.to/alexjcm/generate-database-documentation-with-schemaspy-docker-windows-linux-macos-1hn1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://schemaspy.org/" rel="noopener noreferrer"&gt;SchemaSpy&lt;/a&gt; is a tool that allows you to generate interactive HTML documentation from databases. In this guide, I will use Oracle as an example, but you can also use SchemaSpy with PostgreSQL, MySQL, SQL Server, etc. Thanks to Docker, you can easily run it on Windows, Linux, or macOS. Let's get started! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Docker installed on your system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/desktop/" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;JDBC driver. Tis image includes drivers for:&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;MariaDB&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;jTDS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you use any of these, you do not need to download any drivers.&lt;/p&gt;

&lt;p&gt;Since this guide uses Oracle Database as an example, you will need to download the Oracle JDBC driver &lt;code&gt;ojdbc11.jar&lt;/code&gt; from &lt;a href="https://www.oracle.com/database/technologies/appdev/jdbc-downloads.html" rel="noopener noreferrer"&gt;the Oracle website&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Create the working directory
&lt;/h3&gt;

&lt;p&gt;Open your terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir schemaspy-doc &amp;amp;&amp;amp; cd schemaspy-doc
mkdir drivers output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Add the JDBC driver
&lt;/h3&gt;

&lt;p&gt;Move the downloaded driver (in this case &lt;code&gt;ojdbc11.jar&lt;/code&gt;) into the &lt;code&gt;drivers/&lt;/code&gt; folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Create &lt;code&gt;schemaspy.properties&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;schemaspy.properties&lt;/code&gt; file with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;schemaspy.t=orathin-service
schemaspy.driver=oracle.jdbc.OracleDriver

schemaspy.host=server_or_ip
schemaspy.port=1521
schemaspy.db=db_name
schemaspy.u=database_user
schemaspy.p=database_password
schemaspy.schema=schema_name

schemaspy.norows=true
schemaspy.noviews=true
# Required in Oracle
schemaspy.cat=%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not sure what value to use for the &lt;code&gt;schemaspy.t&lt;/code&gt; parameter? 👀 Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm schemaspy/schemaspy -dbHelp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will get a list of supported database types and the parameters each one requires.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Run SchemaSpy with Docker
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;On Linux/macOS:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm \
  -v "$(pwd)/schemaspy.properties:/schemaspy.properties" \
  -v "$(pwd)/output:/output" \
  -v "$(pwd)/drivers:/drivers" \
  schemaspy/schemaspy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;On Windows:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm `
  -v "${PWD}/schemaspy.properties:/schemaspy.properties" `
  -v "${PWD}/output:/output" `
  -v "${PWD}/drivers:/drivers" `
  schemaspy/schemaspy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you use &lt;code&gt;localhost&lt;/code&gt; as the database host within the Docker container, it will not work because &lt;code&gt;localhost&lt;/code&gt; points to the container itself, not to your host machine. ⚠️&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Use &lt;code&gt;host.docker.internal&lt;/code&gt; as the host to connect from the container to your local machine. For example:&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;schemaspy.host=host.docker.internal
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 5: View the generated documentation
&lt;/h3&gt;

&lt;p&gt;Once the command finishes, open the &lt;code&gt;output/index.html&lt;/code&gt; file in your favorite web browser. You’ll find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entity relationship diagrams&lt;/li&gt;
&lt;li&gt;Table structures&lt;/li&gt;
&lt;li&gt;Columns, indexes, relationships, etc&lt;/li&gt;
&lt;li&gt;A beautiful (and clickable!) and interactive HTML interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example Output&lt;/strong&gt; 📸&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8mill8edp2czmc73z43n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8mill8edp2czmc73z43n.png" alt="Sample 1" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstu1vilqqub2ji4142vt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstu1vilqqub2ji4142vt.png" alt="Sample 2" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>schemaspy</category>
      <category>documentation</category>
      <category>database</category>
      <category>docker</category>
    </item>
    <item>
      <title>REST API Load performance testing using JMeter</title>
      <dc:creator>Alex John Chamba</dc:creator>
      <pubDate>Thu, 30 Jan 2025 03:14:58 +0000</pubDate>
      <link>https://dev.to/alexjcm/rest-api-load-performance-testing-using-jmeter-p8k</link>
      <guid>https://dev.to/alexjcm/rest-api-load-performance-testing-using-jmeter-p8k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://jmeter.apache.org/index.html" rel="noopener noreferrer"&gt;JMeter&lt;/a&gt; is the perfect tool to test the performance of your REST API. In this guide, I'll show you how to set it up and run a load test in minutes in a straightforward way. Let's get started! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;JMeter installed.&lt;/li&gt;
&lt;li&gt;A REST API to test (we will use &lt;a href="https://restcountries.com/v3.1/translation/germany" rel="noopener noreferrer"&gt;https://restcountries.com/v3.1/translation/germany&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuring the Test Plan
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Add a Thread Group&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open JMeter and right click on &lt;code&gt;Test Plan -&amp;gt;  Add -&amp;gt; Threads -&amp;gt; Thread Group&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fds7amgoerxpbvqvqa9wx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fds7amgoerxpbvqvqa9wx.png" alt="Add Thread Group" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Add an HTTP Request&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Right click on &lt;code&gt;Thread Group -&amp;gt; Add -&amp;gt; Sampler -&amp;gt; HTTP Request&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Fill in the necessary values&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Method: GET&lt;/li&gt;
&lt;li&gt;URL: &lt;a href="https://restcountries.com/v3.1/translation/germany" rel="noopener noreferrer"&gt;https://restcountries.com/v3.1/translation/germany&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xo7u3z41z8rrrocojbr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xo7u3z41z8rrrocojbr.png" alt="Fill HTTP values" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Add a Listener to see the Request response&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Right click on &lt;code&gt;Thread Group -&amp;gt; Add -&amp;gt; Listener -&amp;gt; View Results Tree&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Save and Run&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Save the changes (this creates a .jmx file), then press the &lt;code&gt;Start&lt;/code&gt; button to run a test.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7czae55c3xpj1koqx9yc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7czae55c3xpj1koqx9yc.png" alt="Save" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;View results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl44jd0ld8trck3dr43i2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl44jd0ld8trck3dr43i2.png" alt="View Results" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Update Thread properties&lt;/strong&gt;&lt;br&gt;
Adjust the thread properties according to the load level you want to simulate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgegthe9436oio2avrjcp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgegthe9436oio2avrjcp.png" alt="Update Thread" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Running the Load Test
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Optimizing JMeter 🛠️ (Optional)
&lt;/h3&gt;

&lt;p&gt;To avoid JMeter consuming too many resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use as few Listeners as possible.&lt;/li&gt;
&lt;li&gt;Don't use "View Results Tree" or "View Results in Table" listeners during the load test, use them only during Test Plan creation and debugging. Disable the listener by right-clicking &lt;code&gt;View Results Tree -&amp;gt; Disable&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Make sure you have Java 21 installed.&lt;/li&gt;
&lt;li&gt;Increase Java Heap size to 2 GB or more, this depends on your test plan and number of threads you want to run. To do this, create a &lt;code&gt;setenv.sh&lt;/code&gt; file in the JMeter &lt;code&gt;bin&lt;/code&gt; directory:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This is the example file jmeter/libexec/bin/setenv.sh&lt;/span&gt;

&lt;span class="c"&gt;# Use a bigger heap, but a smaller metaspace, than the default&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HEAP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-Xms2G -Xmx2G -XX:MaxMetaspaceSize=192m"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Running JMeter in CLI Mode
&lt;/h3&gt;

&lt;p&gt;Once everything is ready, you will use CLI mode (Previously called Non-GUI mode) to run it for the Load Test.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Don't use GUI mode for Load Testing ! Use it only for Test Plan creation and Test Plan debugging.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Run JMeter in CLI mode:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jmeter &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; ~/Documents/View-Results.jmx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run JMeter in CLI mode and generate a report:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jmeter &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; ~/Documents/View-Results.jmx &lt;span class="nt"&gt;-l&lt;/span&gt; ~/Documents/logs/test-results.jtl &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; ~/Documents/results/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parameters used:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-n&lt;/code&gt;, run JMeter in CLI mode&lt;br&gt;
&lt;code&gt;-t &amp;lt;argument&amp;gt;&lt;/code&gt;, name of .jmx file that contains the Test Plan to run&lt;br&gt;
&lt;code&gt;-l &amp;lt;argument&amp;gt;&lt;/code&gt;, name of .jtl file to log sample results&lt;br&gt;
&lt;code&gt;-e&lt;/code&gt; generate report dashboard&lt;br&gt;
&lt;code&gt;-o &amp;lt;argument&amp;gt;&lt;/code&gt; output folder where to generate the report dashboard (Folder must not exist or be empty)&lt;/p&gt;




&lt;h2&gt;
  
  
  Analyzing the Load Test
&lt;/h2&gt;

&lt;p&gt;Once your Load Test is finished, you can use the HTML report to analyze your load test. To do this, you must open the &lt;code&gt;results/index.html&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Done! You now have a working load test. 🚀&lt;/p&gt;

</description>
      <category>jmeter</category>
      <category>performance</category>
      <category>loadtesting</category>
    </item>
  </channel>
</rss>
