<?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" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Neumeral - Medium]]></title>
        <description><![CDATA[Stories on how to leverage tech and data to redefine your business - Medium]]></description>
        <link>https://medium.com/neumeral?source=rss----dd629057312---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Neumeral - Medium</title>
            <link>https://medium.com/neumeral?source=rss----dd629057312---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 17 May 2026 10:08:24 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/neumeral" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Delayed Job as a Rake Task]]></title>
            <link>https://medium.com/neumeral/delayed-job-as-a-rake-task-4ddb4ef2b39b?source=rss----dd629057312---4</link>
            <guid isPermaLink="false">https://medium.com/p/4ddb4ef2b39b</guid>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[code]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Awin Abi]]></dc:creator>
            <pubDate>Wed, 06 Aug 2025 14:33:19 GMT</pubDate>
            <atom:updated>2019-03-10T10:56:28.186Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-LlBS9HIXlDTtjYIkkutVw.jpeg" /></figure><p>Delayed Job is a great and simple solution for background jobs in a Rails application. But if you don’t have the memory or resources to run a background thread 24 hours on a server what do you do?</p><p>We were in a similar situation for a client, who was strictly on a shoe string budget, running on Heroku. The background job was to process some applications, verify and sent emails if they had errors. This was to be done once a day. Running a background job just for this was a bad choice.</p><p>Another option was to run this as a rake task, at a set time, use <a href="https://elements.heroku.com/addons/scheduler">Heroku Scheduler</a> to run this at 04:00am every day. But we wanted to try a bit more generic solution.</p><p>We decided to stick to write Delayed Job classes, so that in future, it can serve both the purposes.</p><ol><li>For more background processing, more jobs we just have to write new classes with perform methods</li><li>When the app is moved into it’s own private hosting VPS, run a background thread more often, to scale it.</li></ol><p>But in the current setup, we had to run the jobs as a rake task, triggered once a day at a specific time, while leaving room for a full fledged background process in the future.</p><p>Looking at the <a href="https://github.com/collectiveidea/delayed_job">delayed_job source at Github</a> we figured that this could be easily implemented. It internally creates a Delayed::Worker class and works off all the jobs in the delayed_jobs table.</p><p>The solution was really simple. Create a rake task in lib/tasks/delayed_job.rake</p><pre># File lib/tasks/delayed_job.rake</pre><pre>namespace :delayed_job do <br>  desc &#39;Run Delayed job worker&#39; <br>  task work: :environment do <br>    worker = Delayed::Worker.new worker.work_off <br>    #by default runs 100 rows <br>  end <br>end</pre><p><strong>For more information on the sources:</strong></p><ul><li>The rake task for starting delayed job — <a href="https://github.com/collectiveidea/delayed_job/blob/c7a42fb78dc538de46024eb36b31e72916ff21a0/lib/delayed/tasks.rb#L8">delayed/tasks.rb</a></li><li>The Delayed::Worker start — <a href="https://github.com/collectiveidea/delayed_job/blob/c7a42fb78dc538de46024eb36b31e72916ff21a0/lib/delayed/worker.rb#L156">delayed/worker.rb</a></li><li>Delayed::Worker work_off definition — <a href="https://github.com/collectiveidea/delayed_job/blob/c7a42fb78dc538de46024eb36b31e72916ff21a0/lib/delayed/worker.rb#L206">delayed/worker.rb#work_off</a></li></ul><p><strong><em>If you found this article useful, please click on the 👏 button a few times to make others find the article and show your support!</em></strong></p><figure><a href="https://blog.hash32.com"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*E9W_wdsVDFKdBqpoidOg0A.jpeg" /></a></figure><p><em>Originally published at </em><a href="https://blog.hash32.com/delayed-job-as-a-rake-task/"><em>blog.hash32.com</em></a><em> on March 4, 2019. </em><strong>Credits -</strong> Header <a href="https://unsplash.com/photos/kR3ahGAazxc">photo by Elisa Michelet</a> on Unsplash.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4ddb4ef2b39b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/neumeral/delayed-job-as-a-rake-task-4ddb4ef2b39b">Delayed Job as a Rake Task</a> was originally published in <a href="https://medium.com/neumeral">Neumeral</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How small can a Ruby on Rails app be?]]></title>
            <link>https://medium.com/neumeral/rack-and-rails-applications-b42922d61146?source=rss----dd629057312---4</link>
            <guid isPermaLink="false">https://medium.com/p/b42922d61146</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[rails-5]]></category>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[ruby]]></category>
            <dc:creator><![CDATA[Awin Abi]]></dc:creator>
            <pubDate>Wed, 06 Aug 2025 14:28:45 GMT</pubDate>
            <atom:updated>2018-12-19T15:55:22.663Z</atom:updated>
            <content:encoded><![CDATA[<p>Ruby on Rails is one of the most popular web frameworks in Ruby. But, did your know that a Rails app can be written in <em>under 20 lines of code</em> in a single file? And you can customize the layout, to fit your needs.</p><p>All that is possible by running Rails as a rack application. See how below.</p><h3><strong>First things first - so what is Rack?</strong></h3><p>Rack provides a modular interface for developing web apps in Ruby. A Rack::Handler connects webservers with Rack. By default it ships with handlers for many Ruby servers like Thin and WEBRick. It also provides a handy rackup commandline tool, which internally starts a Rack::Server.</p><p>Any object that responds to a call function and takes an env hash as parameter, returning an Array with the http response code, hash of headers, and a response body that can respond to each.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*l4urxZ6B952VC62aHNUDjg.jpeg" /></figure><p>For example the below instance of the class RunMe. You can run this with a Rack Handler.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4382beb8425740ce3180be0e64910325/href">https://medium.com/media/4382beb8425740ce3180be0e64910325/href</a></iframe><p>Save all of this in a server.rb and run it with ruby server.rb.</p><p>The rackup command line tool can be used, in which case you can forego the explicit use of the WEBrick handler. rackup internally calls Rack::Server.start</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/90fe592265435b0b4a1f71caf0024c3d/href">https://medium.com/media/90fe592265435b0b4a1f71caf0024c3d/href</a></iframe><h3><strong>Running the Rails Application on Rack</strong></h3><p>When rails server is called the start method of Rails::Server is called. Rails::Server inherits from Rack::Server.</p><p>Rails::Application is an class with a call function and has all the properties of [1]. So if we define a class that inherits from Rails::Application we can serve it with.</p><p>So lets create a simple Rails::Application. Create a file named config.ru as follows:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/04108c71cbf6feb8e075fd0068d88afc/href">https://medium.com/media/04108c71cbf6feb8e075fd0068d88afc/href</a></iframe><p>This just prints ‘Hello World’. For a more useful experiment, you can define a controller and render a template.</p><p>Lets create a PagesController that renders some html inline.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/55f0bcbc5a1f86a1c3ba1dce98e829fd/href">https://medium.com/media/55f0bcbc5a1f86a1c3ba1dce98e829fd/href</a></iframe><p>This right here, is a Rails application in a single file, with just 16 <em>lines</em> of Ruby. Well pretty small, huh! If you need to build something useful with this, it will be well beyond 16 lines of course, but you can fit all of it in a single file.</p><p>You can use this for running specialized applications on Rack, with the features of Rails, and you can pick and choose which ones. Load only the libraries and middlewares you use in Rails and run the app on Rack.</p><blockquote>You can split up the views to a separate folder, models into separate files and use require_relative to use them. Or organize folders based on functionality. Or bring a folder structure that fit your needs.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/522/1*H4IdWE7Px0e7epbvJYT0Qw.png" /><figcaption>Sample Rails application on Rack folder structure.</figcaption></figure><p>You can find the source for this article, and more examples in the <a href="https://github.com/HASH32/rails-and-rack">https://github.com/HASH32/rails-and-rack</a> repository.</p><h3><strong>References</strong></h3><ul><li>Read the official Ruby on Rails guide on <a href="https://guides.rubyonrails.org/rails_on_rack.html">Rails on Rack</a>.</li><li>Watch this talk by José Valim — <a href="http://bit.ly/2BnT4W2">You’ve got a Sinatra on your Rails</a></li></ul><p><strong>PS:</strong> This article was originally posted in <a href="https://blog.hash32.com/rails-as-rack-app/">HASH32 Engineering Blog</a>.</p><blockquote>If you found this article useful, please click on the 👏 button a few times to make others find the article and show your support!</blockquote><blockquote><strong><em>Don’t forget to follow me, to get notified of upcoming articles like these.</em></strong></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b42922d61146" width="1" height="1" alt=""><hr><p><a href="https://medium.com/neumeral/rack-and-rails-applications-b42922d61146">How small can a Ruby on Rails app be?</a> was originally published in <a href="https://medium.com/neumeral">Neumeral</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rails Performance Monitoring Tools Compared]]></title>
            <link>https://medium.com/neumeral/rails-performance-monitoring-tools-compared-82ac47033095?source=rss----dd629057312---4</link>
            <guid isPermaLink="false">https://medium.com/p/82ac47033095</guid>
            <category><![CDATA[engineering]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[coding]]></category>
            <dc:creator><![CDATA[Awin Abi]]></dc:creator>
            <pubDate>Wed, 06 Aug 2025 14:21:10 GMT</pubDate>
            <atom:updated>2019-12-17T10:23:39.666Z</atom:updated>
            <content:encoded><![CDATA[<p>You should monitor your Rails application regularly, to find performance bottlenecks. Here are some tools that help you achieve this.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_P1Fza_6BbBouy-iTU1PBQ.jpeg" /></figure><h3>1. Using rack_mini_profiler gem</h3><p>Install it by adding the gem &#39;rack_mini_profiler&#39; to your Gemfile. If you append your url with the pp parameter, you will get to see some options for Rack Mini Profiler.</p><p>For example, running locally <a href="http://localhost:3000/?pp=help">http://localhost:3000/?pp=help</a> — shows the help screen.</p><h4>Memory Profiling</h4><p>To find which gems and files are using the memory, accessing the url <a href="http://localhost:3000/?pp=profile-memory">http://localhost:3000/?pp=profile-memory</a> — will show the memory profile.</p><p>This requires gem &#39;memory_profiler&#39; to be added to the Gemfile.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1023/0*puSoFs4_GfR2Hxxp.png" /><figcaption>Sample profiler output</figcaption></figure><p>As you can see above, gems like newrelic_rpm, meta_requests etc are adding to the memory consumed by the Rails app; so its important to add them to the right group in the Gemfile.</p><h4>Flamegraph of the Stack</h4><p>Add the following gems to show the flamegraph of the call stack with rack_mini_profiler.</p><pre>gem &#39;flamegraph&#39; gem &#39;stackprof&#39;</pre><p>It can show the flamegraph of the call stack. For more about how to interpret the famegraph read <a href="https://www.justinweiss.com/articles/a-new-way-to-understand-your-rails-apps-performance/">Rails App’s Performance blog post</a> by Justin Weiss.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*GDPgwgM5xUi8nge1.png" /><figcaption>Flamegraph of a sample Rails route</figcaption></figure><h3>2. Rails Panel</h3><p>If you are using Google Chrome, there is a handy Chrome extension called Rails Panel. Download it from the <a href="https://chrome.google.com/webstore/detail/railspanel/gjpfobpafnhjhbajcjgccbbdofdckggg">chrome web store</a>.</p><p>This extension will show you the breakdown of time taken in Rendering, ActiveRecord etc.</p><p>The gem &#39;meta_request&#39; needs to be added to the development group in the Gemfile, for the data to appear in Rails panel.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uL3PWuodXzETxdRuybuarA.png" /><figcaption>Output in Rails Panel</figcaption></figure><h3>3. Scout DevTrace</h3><p>Using the scout agent (add gem &#39;scout_apm&#39; in the Gemfile) in development mode will show a beautiful panel with the breakdown of time consumed in various sections - Views, Middleware, ActiveRecord, controllers etc. It also shows N+1 queries and backtraces.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*S4GGo3xPHaAhEH2gMpeB2A.png" /><figcaption>DevTrace from Scout APM</figcaption></figure><p>You need to start the server with the environment variable SCOUT_DEV_TRACE=true for this.</p><pre>$ SCOUT_DEV_TRACE=true be rails server</pre><h3>4. Derailed Benchmarks</h3><p><a href="https://github.com/schneems/derailed_benchmarks">Derailed Benchmarks gem</a> can be used for a variety of tasks. Well, the gem has packaged common performance into rake tasks. Read the code here — <a href="https://github.com/schneems/derailed_benchmarks/blob/master/lib/derailed_benchmarks/tasks.rb">derailed_benchmarks#tasks.rb</a>.</p><h4>Gem-wise memory consumption</h4><p>Running the following command will give the list of gems used in the app, along with the memory they consume.</p><pre>bundle exec derailed bundle:mem</pre><h4>Identify memory leaks</h4><p>For running memory and stack profilers you need to prepare your app to run in RAILS_ENV=production. The following needs to be taken care of:</p><ul><li>Disable ssl configuration for the test config.force_ssl = false in environments/production.rb. Troubleshooting - Read <a href="https://gist.github.com/hash32bot/14750b9eea739374ca69dc3182ca99a3">this Gist</a>.</li><li>Check database for production and the secrets file.</li><li>Use the same server as you use in production. Derailed by default uses Rack::Mock by default.</li><li>Configure authentication <a href="https://github.com/schneems/derailed_benchmarks#authentication">as per the documentation</a>.</li></ul><p>Running perf:mem_over_time will boot up the app and show the memory consumed by the app, as its hit by a larger amount of requests.</p><pre>USE_SERVER=puma bundle exec derailed exec perf:mem_over_time</pre><p>If the memory remains constant after a point, then the app does not have any memory leaks. But if the memory keeps increasing, it is an indication of a memory leak.</p><p>You can debug further by looking at the objects in the memory</p><pre>bundle exec derailed exec perf:objects </pre><pre># OR get a Heap Dump <br>bundle exec derailed exec perf:heap</pre><h3>5. Using fasterer gem</h3><p><a href="https://github.com/DamirSvrtan/fasterer">fasterer gem</a> is not exactly a monitoring tool, but it will give suggestions on Ruby speed improvements. This is not Rails specific, but generic Ruby.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*u3DKRabvnzbewbJV.png" /><figcaption>Sample output of the fasterer gem.</figcaption></figure><p>There is also a <a href="https://github.com/JuanitoFatas/fast-ruby">fast-ruby repo</a>, which has benchmarks of fast and slow Ruby code.</p><h3>6. Using bullet gem</h3><p>Eliminating N+1 queries can improve the application speed drastically.<br> Use the <a href="https://github.com/flyerhzm/bullet">bullet gem</a> to identify and remove N+1 queries.</p><h3>7. Newrelic Agent</h3><p>The developer panel of Newrelic has been removed in the newer editons of the gem. <br> For viewing this an old gem version &#39;~&gt; 4.0.0&#39; has to be used.</p><pre>gem &#39;newrelic_rpm&#39;, &#39;4.0.0.332&#39;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*95COx1-UTBM3K83bVPtEag.png" /></figure><p><strong><em>If you found this article useful, please click on the 👏 button a few times to make others find the article and show your support!</em></strong></p><p><strong>Credits:</strong> Header <a href="https://unsplash.com/photos/LfEUDdg6yQs">photo by Markus Spiske</a> on Unsplash.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=82ac47033095" width="1" height="1" alt=""><hr><p><a href="https://medium.com/neumeral/rails-performance-monitoring-tools-compared-82ac47033095">Rails Performance Monitoring Tools Compared</a> was originally published in <a href="https://medium.com/neumeral">Neumeral</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GraphQL with Sinatra (Ruby) — Part 2— Mutations]]></title>
            <link>https://medium.com/neumeral/graphql-with-sinatra-ruby-part-2-mutations-d6903699af3e?source=rss----dd629057312---4</link>
            <guid isPermaLink="false">https://medium.com/p/d6903699af3e</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[graphql]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ruby]]></category>
            <dc:creator><![CDATA[Awin Abi]]></dc:creator>
            <pubDate>Wed, 06 Aug 2025 14:20:53 GMT</pubDate>
            <atom:updated>2018-12-25T14:57:22.148Z</atom:updated>
            <content:encoded><![CDATA[<h3>GraphQL with Sinatra (Ruby) — Part 2— Mutations</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WQ2En5fbuwFHkXPm2tmClw.jpeg" /><figcaption>Honeycomb Facade — Photo by <a href="https://unsplash.com/@chuttersnap">chuttersnap</a> on <a href="https://unsplash.com/search/photos/bees?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h4>In this post let’s see how to create GraphQL mutations to add a speaker to our database.</h4><p>In Part 1 of this series talks about how to set things up, and how to define a query to get a list of Speakers from our Conference GraphQL API.</p><p><a href="https://medium.com/hash32/graphql-server-with-sinatra-ruby-part-1-fdd664170715">GraphQL server with Sinatra (Ruby) — Part 1</a></p><p>A mutation is something that mutates or changes the data in the server. In DB terms, if we need to change the data in a table using graphql we need mutations — be it an INSERT, UPDATE or DELETE. Only SELECTs are covered with a Query.</p><blockquote><strong><em>Note: Updated to the new class-based API, which was introduced in version 1.8 of the gem. While the </em></strong><strong><em>define DSL based syntax will still work, it will eventually get </em></strong><a href="http://graphql-ruby.org/schema/class_based_api.html#roadmap"><strong><em>removed in version 2.0</em></strong></a><strong><em>.</em></strong></blockquote><p>So to add a new speaker to the database we need a mutation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/906/1*MzBfYaBAG2sswbUCZby4Rg.jpeg" /><figcaption>Adding data to the application via Mutations</figcaption></figure><p>In the GraphQL language, a mutation is of the form</p><pre>mutation AddSpeaker($name:String, $talkTitle:String) {<br>  createSpeaker(name: $name, talkTitle:$talkTitle) {<br>    success<br>    errors<br>  }<br>}</pre><p>A set of “query” variables needs to be supplied to the GraphQL endpoint.<br>Say for example,</p><pre><br>{<br>  &quot;name&quot;: &quot;John Doe&quot;,<br>  &quot;talkTitle&quot;: &quot;Introduction to GraphQL in Ruby&quot;<br>}<br></pre><p>Read more about GraphQL mutations and its syntax in the specifications — <a href="https://graphql.org/learn/queries/#mutations">https://graphql.org/learn/queries/#mutations</a></p><p>For our little server to accept mutations, we need to make some changes and add more files for defining mutations. Lets see how, step-by-step.</p><h3><strong>STEP 5: Adding a Mutation root type</strong></h3><p>A mutation root MutationType has to be created and it should then be added to our Schema, like the QueryType that was added in the last post.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/477376836ed9c2953d246dccc0d3b894/href">https://medium.com/media/477376836ed9c2953d246dccc0d3b894/href</a></iframe><h3>STEP 6: Define a Mutation for speaker creation</h3><p>Next, we need to tell GraphQL about the parameters that needs to be accepted for creating a new speaker.</p><p>Let’s split this into a separate file, that handles this mutation — create_speaker.rb. Instead of inheriting from GraphQL::Schema::Mutation we create a mutation base class Mutations::BaseMutation. Also lets group all the mutations in mutations folder.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1301b183eb4403b83cceef06cc33566d/href">https://medium.com/media/1301b183eb4403b83cceef06cc33566d/href</a></iframe><p>It needs to accept all the fields for a speaker, which we created as strings in the DB. In GraphQL ruby, strings are represented with the String type, as defined in the gem.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/06b6c2faf4b05fef52177c6072e8a525/href">https://medium.com/media/06b6c2faf4b05fef52177c6072e8a525/href</a></iframe><p>Next we need to take these fields and then call speaker.save with the defined input fields in the resolve function.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6f66a3828236db0be578fbb173a0d6c9/href">https://medium.com/media/6f66a3828236db0be578fbb173a0d6c9/href</a></iframe><p>This returns a hash with success and errors. We need to tell GraphQL about it as well. Note: errors is an array of Strings. We define these as fields in the mutation.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f1de85f71b05e662ba09d53f632e3070/href">https://medium.com/media/f1de85f71b05e662ba09d53f632e3070/href</a></iframe><p>Now the CreateSpeaker mutation is complete. It needs to be added to the root mutation — MutationType so that it gets included in the schema.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/22405ff34451afd5bc06aa773ce2c7e2/href">https://medium.com/media/22405ff34451afd5bc06aa773ce2c7e2/href</a></iframe><p>Restart the server with bundle exec puma.</p><p>If you use a client like <a href="https://github.com/skevy/graphiql-app/releases">GraphiQL,</a> you should be able to see the docs in the right sidebar changes and now has a Mutation.</p><p>Add a new speaker, with the mutation and the query variables in the client.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8003810d052740637015749c39165609/href">https://medium.com/media/8003810d052740637015749c39165609/href</a></iframe><p>Execute the mutation in the GraphiQL client. You should be able to see the response data json, with something like below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5qjpF7LOLPnC1YI4aMJG9g.png" /><figcaption>Successful mutation execution — GraphiQL client</figcaption></figure><p>The CreateSpeaker mutation has all the fields optional, but the Speaker model validates the presence of the name field. If you try to create a speaker without giving a name field, it will show up in errors return field.</p><p>We can avoid this validation at the schema level, by making the required argument mandatory. You just need to change null: false to the respective arguments.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/792bb1ebfc91f0c7e94acc7f137eafe7/href">https://medium.com/media/792bb1ebfc91f0c7e94acc7f137eafe7/href</a></iframe><p>Now the name and talk_title fields are non-nullable fields, and you’ll have to always give these fields when executing the mutation. Read about the <a href="https://graphql.org/learn/schema/#type-system">type system in the official documentation</a>.</p><h3>Show me the code</h3><p>You can see all the code for this post in the <a href="https://github.com/awinabi/sinatra-graphql"><strong>sinatra-graphql</strong></a> Github repository.</p><blockquote>If you found this article useful, please click on the 👏 button a few times to make others find the article and show your support!</blockquote><blockquote><strong><em>Don’t forget to follow me, to get notified of upcoming articles like these.</em></strong></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d6903699af3e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/neumeral/graphql-with-sinatra-ruby-part-2-mutations-d6903699af3e">GraphQL with Sinatra (Ruby) — Part 2— Mutations</a> was originally published in <a href="https://medium.com/neumeral">Neumeral</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GraphQL server with Sinatra (Ruby) — Part 1]]></title>
            <link>https://medium.com/neumeral/graphql-server-with-sinatra-ruby-part-1-fdd664170715?source=rss----dd629057312---4</link>
            <guid isPermaLink="false">https://medium.com/p/fdd664170715</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[sinatra]]></category>
            <category><![CDATA[graphql]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[Awin Abi]]></dc:creator>
            <pubDate>Wed, 06 Aug 2025 14:20:33 GMT</pubDate>
            <atom:updated>2018-12-25T14:00:22.556Z</atom:updated>
            <content:encoded><![CDATA[<h3>GraphQL server with Sinatra (Ruby) — Part 1</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Rcd8cYaC0iwjVRmBoR3RQA.jpeg" /><figcaption>Web in the morning — Photo by <a href="https://unsplash.com/photos/h7dl6upIOOs?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Robert Anasch</a> on <a href="https://unsplash.com/search/photos/node-network?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><blockquote><strong>Updated to the new </strong><a href="http://graphql-ruby.org/schema/class_based_api.html"><strong>class-based API</strong></a><strong>, graphql gem version 1.8+</strong></blockquote><p>GraphQL has redefined the way we deal with APIs and endpoints. With the client being able to specify the fields it needs, development in the client could in one way be independent of the server changes, if a schema is predefined.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/780/1*hKoadlrAuOG-5SOWIWueoA.jpeg" /><figcaption>GraphQL + Sinatra — create a graphql endpoint in the lightweight micro framework.</figcaption></figure><p>We’ll see how to create a GraphQL server using the Sinatra framework in Ruby. In this example we will be creating the schema for a conference app, where you can add speakers and list them.</p><h3><strong>STEP 1: Create a Sinatra application</strong></h3><p>I wish there was a template to create a sinatra application using a cli. But there isn’t a lot of boilerplate files to create, so lets add it one-by-one.</p><p>We’ll be using puma as the server. Create an app.rb file which defines a basic sinatra app with a / route. Also a Gemfile is added and bundle install is run.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/26a246cce86aa75ca01cd32577eb6cc7/href">https://medium.com/media/26a246cce86aa75ca01cd32577eb6cc7/href</a></iframe><p>Next we need a rackup file config.ru so that puma will pickup the app as a rack application.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2942dfe8add130fcb77a2d44efe49dfa/href">https://medium.com/media/2942dfe8add130fcb77a2d44efe49dfa/href</a></iframe><p>Running the puma server will serve your application at <a href="http://localhost:9292,">http://localhost:9292,</a> and you should see the message <em>‘It Works!’</em>.</p><pre>bundle exec puma</pre><p>Yay! The app is up.</p><h3><strong>STEP 2: Add JSON responses</strong></h3><p>For the server to respond to JSON, we add the<a href="https://github.com/sinatra/sinatra/tree/master/sinatra-contrib"> </a><a href="https://github.com/sinatra/sinatra/tree/master/sinatra-contrib">sinatra-contrib</a> gem, which adds a json helper. Change the app.rb file to respond to json.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/069ac04c192be8fdeec996ee3c9e6e6d/href">https://medium.com/media/069ac04c192be8fdeec996ee3c9e6e6d/href</a></iframe><p>Now our app contains just these files:</p><pre>conference_app<br>  |<br>  ├── Gemfile<br>  ├── Gemfile.lock<br>  ├── app.rb<br>  └── config.ru</pre><h3><strong>STEP 3: Add database connections and models with ActiveRecord</strong></h3><p>For talking to the database, we’ll use activerecord gem.</p><p><strong>Add database configuration to connect to sqlite3</strong></p><p>Also add a configuration file database.yml with the connection details and the sqlite3 gem for connecting to the sqlite database. app.rb needs changes to update this configuration.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e9adc8cc48d65760ca234090d5ef027c/href">https://medium.com/media/e9adc8cc48d65760ca234090d5ef027c/href</a></iframe><p><strong>Add Rakefile</strong></p><p>Add the rake gem along with the Rakefile. This gives handy rake tasks for creating the table (migrations) and managing them.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fb9467dec4770f603d64073b3e789c7a/href">https://medium.com/media/fb9467dec4770f603d64073b3e789c7a/href</a></iframe><p>bundle exec rake -T will display the added rake tasks.</p><p>Create the sqlite database, by running bundle exec rake db:create</p><p><strong>Add a migration and model for Speaker object</strong></p><p>Create a migration with the following rake command:</p><pre>bundle exec rake db:create_migration NAME=create_speakers</pre><p>Change the created migration file in <em>db/migrate </em>folder, to add the required database fields.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2c0d9fae4cc51994967e8443524d088e/href">https://medium.com/media/2c0d9fae4cc51994967e8443524d088e/href</a></iframe><p>Run migrations with the rake task bundle exec rake db:migrate</p><p>Create a model file for <em>Speaker</em>, to access this table.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/261c265213c71dd5442ad589f7e1496b/href">https://medium.com/media/261c265213c71dd5442ad589f7e1496b/href</a></iframe><p>I’ve added a basic validation for the model. Read more on activerecord basics in the <a href="http://guides.rubyonrails.org/active_record_basics.html">official basics introduction</a>.</p><p>Add the pry gem for debugging and execute the following two statements in the pry console, for adding rows to the speakers table.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/966/1*Hg__fHQy7s6e9kr-bUmp6g.png" /><figcaption>Use pry to create records for Speaker model.</figcaption></figure><pre>require &#39;./app&#39;</pre><pre>Speaker.create(name: &#39;John&#39;, twitter_handle: &#39;johnruby&#39;, bio: &#39;This is John\&#39;s bio&#39;, talk_title: &#39;How to bootstrap a sinatra application&#39;)</pre><pre>Speaker.create(name: &#39;Jacob&#39;, twitter_handle: &#39;jacob-ruby&#39;, bio: &#39;This is Jacob\&#39;s bio&#39;, talk_title: &#39;Introduction to graphql&#39;)<br></pre><p><strong>Add a </strong><strong>/speakers endpoint</strong></p><p>Create a new endpoint to show the list of speakers, as JSON.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f1442a7921f8b9452d894428ff158698/href">https://medium.com/media/f1442a7921f8b9452d894428ff158698/href</a></iframe><h3><strong>STEP 4: Add graphql and define a query to list speakers</strong></h3><p>Now we have a sinatra app that connects to the database and shows a list of speakers as a JSON response. Now let’s add graphql and define a schema for speakers.</p><p>Add the graphql gem. <a href="https://github.com/rmosolgo/graphql-ruby">https://github.com/rmosolgo/graphql-ruby</a>. Read the documentation at <a href="http://graphql-ruby.org/">http://graphql-ruby.org/</a>.</p><p>Also the rack-contrib gem needs to be added so that the sinatra app can accept raw JSON payloads.</p><p><strong>Add type, query and schema for graphql</strong></p><p>Now we need to add a type for <em>Speaker</em>, also a query and a schema for GraphQL.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/19f1811540ba8ea72e4a2155b95cf549/href">https://medium.com/media/19f1811540ba8ea72e4a2155b95cf549/href</a></iframe><p>We need to then add a root query.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f754af1e761ec2422384afb01a17902f/href">https://medium.com/media/f754af1e761ec2422384afb01a17902f/href</a></iframe><p>Define a schema for GraphQL.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/61af1b7e4cf72f48ef674533928e8997/href">https://medium.com/media/61af1b7e4cf72f48ef674533928e8997/href</a></iframe><p><strong>The </strong><strong>/graphql endpoint</strong></p><p>We now need to have a POST endpoint for GraphQL.</p><p>GraphQL schema can be executed to give a GraphQL::Query::Result which can then be converted to JSON. app.rb needs change to include this endpoint.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ab89ca820d8e89b99fb36e951b4ab63e/href">https://medium.com/media/ab89ca820d8e89b99fb36e951b4ab63e/href</a></iframe><p><strong>Querying the endpoint</strong></p><p>You can use the <a href="https://github.com/skevy/graphiql-app/releases">GraphiQL</a> app or the <a href="https://www.getpostman.com/">Postman</a> app to query the endpoint. Make sure that you have puma running and the server is up.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/824/1*qlVTo-ZOf2xowaCLxaNXQA.png" /><figcaption>Querying the graphql endpoint in Postman</figcaption></figure><p>A JSON response like the below will be obtained.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b072d8f679eb67536aabfdf7e301b3ee/href">https://medium.com/media/b072d8f679eb67536aabfdf7e301b3ee/href</a></iframe><p>That’s it for now. You have a GraphQL server up and running on sinatra, and you can query the endpoint to get a list of speakers with the fields defined in the GraphQL query.</p><h3><strong>Source Code</strong></h3><p>The source code is available at <a href="https://github.com/awinabi/sinatra-graphql">https://github.com/awinabi/sinatra-graphql</a></p><p>In Part 2 of this series, we’ll see how to add a mutation to add a new <strong><em>Speaker</em></strong>.</p><p><a href="https://medium.com/hash32/graphql-with-sinatra-ruby-part-2-mutations-d6903699af3e">GraphQL with Sinatra (Ruby) — Part 2— Mutations</a></p><blockquote>If you found this article useful, please click on the 👏 button a few times to make others find the article and show your support!</blockquote><blockquote><strong><em>Don’t forget to follow me, to get notified of upcoming articles like these.</em></strong></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fdd664170715" width="1" height="1" alt=""><hr><p><a href="https://medium.com/neumeral/graphql-server-with-sinatra-ruby-part-1-fdd664170715">GraphQL server with Sinatra (Ruby) — Part 1</a> was originally published in <a href="https://medium.com/neumeral">Neumeral</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>