<?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: Lucas Luan de Melo</title>
    <description>The latest articles on DEV Community by Lucas Luan de Melo (@lucasldemello).</description>
    <link>https://dev.to/lucasldemello</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%2F1406911%2F4cdb4af8-8ea9-4aff-b444-39fcd8b3638d.jpeg</url>
      <title>DEV Community: Lucas Luan de Melo</title>
      <link>https://dev.to/lucasldemello</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lucasldemello"/>
    <language>en</language>
    <item>
      <title>Rails Routing &amp; APIs: What Actually Happens Between the URL and Your Controller</title>
      <dc:creator>Lucas Luan de Melo</dc:creator>
      <pubDate>Mon, 17 Aug 2026 18:41:58 +0000</pubDate>
      <link>https://dev.to/lucasldemello/rails-routing-apis-what-actually-happens-between-the-url-and-your-controller-4elj</link>
      <guid>https://dev.to/lucasldemello/rails-routing-apis-what-actually-happens-between-the-url-and-your-controller-4elj</guid>
      <description>&lt;p&gt;When I started studying APIs more seriously, I realized there was a problem with the way I was learning.&lt;/p&gt;

&lt;p&gt;I knew how to create a Rails API.&lt;/p&gt;

&lt;p&gt;I knew how to write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:products&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I knew what &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PATCH&lt;/code&gt; and &lt;code&gt;DELETE&lt;/code&gt; were supposed to do.&lt;/p&gt;

&lt;p&gt;But I wasn't always able to explain &lt;strong&gt;why&lt;/strong&gt; things worked the way they did.&lt;/p&gt;

&lt;p&gt;So I decided to go one step back and review the fundamentals: routing, HTTP, REST and how Rails puts all of these things together.&lt;/p&gt;

&lt;p&gt;This is what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rails Routing
&lt;/h2&gt;

&lt;p&gt;At its simplest, routing is the thing that connects a URL to some code in your application.&lt;/p&gt;

&lt;p&gt;In Rails, this happens in &lt;code&gt;routes.rb&lt;/code&gt;.&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 ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;'/about'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s1"&gt;'pages#about'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If someone requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /about
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rails knows that it should call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;PagesController&lt;/span&gt;&lt;span class="c1"&gt;#about&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty straightforward.&lt;/p&gt;

&lt;p&gt;But Rails gets much more interesting when we start using RESTful routes.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;resources&lt;/code&gt; does a lot of work
&lt;/h2&gt;

&lt;p&gt;Instead of manually defining every route for a resource:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;get&lt;/span&gt;    &lt;span class="s1"&gt;'/products'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s1"&gt;'products#index'&lt;/span&gt;
&lt;span class="n"&gt;get&lt;/span&gt;    &lt;span class="s1"&gt;'/products/:id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s1"&gt;'products#show'&lt;/span&gt;
&lt;span class="n"&gt;post&lt;/span&gt;   &lt;span class="s1"&gt;'/products'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s1"&gt;'products#create'&lt;/span&gt;
&lt;span class="n"&gt;patch&lt;/span&gt;  &lt;span class="s1"&gt;'/products/:id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s1"&gt;'products#update'&lt;/span&gt;
&lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="s1"&gt;'/products/:id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s1"&gt;'products#destroy'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rails lets us write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:products&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And generates the conventional CRUD routes for us.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;HTTP Verb&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;code&gt;index&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;code&gt;show&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show one resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;code&gt;new&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Form for a new resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;&lt;code&gt;create&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;code&gt;edit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Form to edit a resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PATCH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;update&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Update a resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;&lt;code&gt;destroy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete a resource&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is one of the reasons Rails feels so productive.&lt;/p&gt;

&lt;p&gt;The framework isn't just giving us routing functionality. It is encouraging a convention.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;resource&lt;/code&gt; vs &lt;code&gt;resources&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This one confused me for a while.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;resources&lt;/code&gt; represents a collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:products&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There can be many products, so Rails generates an &lt;code&gt;index&lt;/code&gt; route.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;resource&lt;/code&gt; represents a single resource:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="ss"&gt;:profile&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There isn't an index because we're talking about one profile.&lt;/p&gt;

&lt;p&gt;It is a small difference, but it makes sense once you think about the resource you're modeling.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;only&lt;/code&gt; and &lt;code&gt;except&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;We don't always need every CRUD action.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:products&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we can be explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or exclude actions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;except: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:destroy&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I generally prefer &lt;code&gt;only&lt;/code&gt; when designing an API because it makes the exposed interface explicit.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;member&lt;/code&gt; vs &lt;code&gt;collection&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Eventually, you'll need an action that doesn't quite fit the standard CRUD operations.&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 ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:products&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;member&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="ss"&gt;:activate&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /products/:id/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part is that &lt;code&gt;activate&lt;/code&gt; operates on &lt;strong&gt;one product&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's what &lt;code&gt;member&lt;/code&gt; means.&lt;/p&gt;

&lt;p&gt;For operations on the collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:products&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="ss"&gt;:download_all&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting route doesn't require a product ID.&lt;/p&gt;

&lt;p&gt;So my mental shortcut is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;member&lt;/code&gt; → one resource&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;collection&lt;/code&gt; → multiple resources / the collection&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Nested resources
&lt;/h2&gt;

&lt;p&gt;Sometimes resources have a natural relationship.&lt;/p&gt;

&lt;p&gt;For example, posts and comments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:posts&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:comments&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Rails can generate routes such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/posts/:post_id/comments
/posts/:post_id/comments/:id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the relationship explicit in the URL.&lt;/p&gt;

&lt;p&gt;But nested routes can also become difficult to maintain when taken too far. So just because Rails lets us nest resources doesn't mean we should create five levels of nesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the application becomes an API
&lt;/h2&gt;

&lt;p&gt;Now things get more interesting.&lt;/p&gt;

&lt;p&gt;Imagine we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/v1/products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We probably don't want our API controllers mixed together with our regular web controllers.&lt;/p&gt;

&lt;p&gt;Rails gives us &lt;code&gt;namespace&lt;/code&gt; for this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="ss"&gt;:api&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;defaults: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;format: :json&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="ss"&gt;:v1&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:products&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Api::V1::ProductsController
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and a URL such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/v1/products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is particularly useful when versioning an API.&lt;/p&gt;

&lt;p&gt;We can have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/v1/products
/api/v2/products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with different controllers and behavior behind them.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Versioning is a way of allowing the old world and the new world to exist at the same time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Clients using v1 don't suddenly break because we changed something in v2.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;namespace&lt;/code&gt; vs &lt;code&gt;scope&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;These two can look very similar, but they have an important difference.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;namespace&lt;/code&gt; changes both the URL and the controller module.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="ss"&gt;:api&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="ss"&gt;:v1&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:products&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This maps to something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Api&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;V1&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ProductsController&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;scope&lt;/code&gt;, on the other hand, can change the URL without necessarily changing the controller namespace.&lt;/p&gt;

&lt;p&gt;This becomes useful when organizing routes without wanting to mirror that organization in the controller structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  But what exactly is REST?
&lt;/h2&gt;

&lt;p&gt;This is where I realized I had been using the word "REST" rather casually.&lt;/p&gt;

&lt;p&gt;REST stands for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Representational State Transfer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It comes from Roy Fielding's dissertation and describes an architectural style based on a set of constraints.&lt;/p&gt;

&lt;p&gt;The six constraints are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Client-Server&lt;/li&gt;
&lt;li&gt;Stateless&lt;/li&gt;
&lt;li&gt;Cacheable&lt;/li&gt;
&lt;li&gt;Uniform Interface&lt;/li&gt;
&lt;li&gt;Layered System&lt;/li&gt;
&lt;li&gt;Code on Demand (optional)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The important part here is that REST isn't simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Use JSON and HTTP verbs."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is considerably more to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Client-Server
&lt;/h3&gt;

&lt;p&gt;The client and server have separate responsibilities.&lt;/p&gt;

&lt;p&gt;The client is responsible for the user interface and user experience.&lt;/p&gt;

&lt;p&gt;The server is responsible for the data and business logic.&lt;/p&gt;

&lt;p&gt;They communicate through a defined interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stateless
&lt;/h3&gt;

&lt;p&gt;Each request should contain everything the server needs to understand it.&lt;/p&gt;

&lt;p&gt;The server shouldn't need to remember the state of the previous request in order to process the next one.&lt;/p&gt;

&lt;p&gt;This is one of those concepts that sounds obvious until you start designing distributed systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cacheable
&lt;/h3&gt;

&lt;p&gt;Responses should indicate whether they can be cached.&lt;/p&gt;

&lt;p&gt;Caching isn't just an optimization that happens somewhere in front of your application. It is part of the architectural model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uniform Interface
&lt;/h3&gt;

&lt;p&gt;This is probably the most important part of REST.&lt;/p&gt;

&lt;p&gt;The interface should be consistent.&lt;/p&gt;

&lt;p&gt;Resources should be identified by URLs.&lt;/p&gt;

&lt;p&gt;Resources can be manipulated through representations.&lt;/p&gt;

&lt;p&gt;Messages should be self-descriptive.&lt;/p&gt;

&lt;p&gt;And HATEOAS is part of this constraint as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resource vs Representation
&lt;/h2&gt;

&lt;p&gt;Another distinction that helped me understand REST better:&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;resource&lt;/strong&gt; is the thing we're talking about.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;representation&lt;/strong&gt; is how that resource is presented.&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 plaintext"&gt;&lt;code&gt;Resource:
Product #42

Representation:
{
  "id": 42,
  "name": "Keyboard"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The product is the resource.&lt;/p&gt;

&lt;p&gt;The JSON is its representation.&lt;/p&gt;

&lt;p&gt;The same resource could potentially have different representations, such as JSON or XML.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP is more than GET and POST
&lt;/h2&gt;

&lt;p&gt;When building APIs, it's easy to think about HTTP methods simply as CRUD operations.&lt;/p&gt;

&lt;p&gt;But their semantics matter.&lt;/p&gt;

&lt;p&gt;For example, idempotency is an important concept.&lt;/p&gt;

&lt;p&gt;An operation is idempotent when repeating the same request produces the same intended result.&lt;/p&gt;

&lt;p&gt;Methods such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET
PUT
DELETE
HEAD
OPTIONS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;are defined as idempotent.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PATCH&lt;/code&gt; is more interesting because it &lt;strong&gt;can&lt;/strong&gt; be idempotent, but isn't necessarily so. It depends on what the operation actually does.&lt;/p&gt;

&lt;p&gt;That distinction matters when designing APIs that clients might retry.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP status codes
&lt;/h2&gt;

&lt;p&gt;A good API communicates through status codes.&lt;/p&gt;

&lt;p&gt;Some that I find particularly useful to keep in mind:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;304&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not Modified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;404&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not Found&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;409&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Conflict&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;422&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unprocessable Entity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;429&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Too Many Requests&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;They tell the client something about what happened without requiring the client to interpret an arbitrary application-specific response.&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 plaintext"&gt;&lt;code&gt;422
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can communicate:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The request was understood, but the data isn't valid."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;429
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;basically means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"You're making too many requests. Slow down."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Stateless vs Stateful
&lt;/h2&gt;

&lt;p&gt;This is another distinction worth remembering.&lt;/p&gt;

&lt;p&gt;A stateless server doesn't depend on remembering previous requests from a client.&lt;/p&gt;

&lt;p&gt;A stateful system does.&lt;/p&gt;

&lt;p&gt;For APIs, statelessness is valuable because requests can be handled more independently. This becomes particularly useful when you have multiple application instances behind a load balancer.&lt;/p&gt;

&lt;h2&gt;
  
  
  CORS and OPTIONS
&lt;/h2&gt;

&lt;p&gt;CORS is another thing that tends to appear when working with APIs.&lt;/p&gt;

&lt;p&gt;At a high level, CORS controls whether a browser is allowed to make requests from one origin to another.&lt;/p&gt;

&lt;p&gt;The server can tell the browser which origins, methods and headers are allowed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;OPTIONS&lt;/code&gt; requests are often involved in this process because the browser can use them to determine what the server permits.&lt;/p&gt;

&lt;p&gt;This is one of those topics that feels mysterious until you realize that the browser is enforcing the rules, not your Rails application magically refusing the request.&lt;/p&gt;

&lt;h2&gt;
  
  
  REST vs GraphQL
&lt;/h2&gt;

&lt;p&gt;REST and GraphQL solve some similar problems in different ways.&lt;/p&gt;

&lt;p&gt;With REST, we generally expose multiple endpoints representing resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /products
GET /products/42
GET /products/42/reviews
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server defines the representation returned by each endpoint.&lt;/p&gt;

&lt;p&gt;With GraphQL, we typically have a single endpoint and the client specifies which data it wants.&lt;/p&gt;

&lt;p&gt;A very simplified mental model is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;REST is several doors with a fixed menu.&lt;/p&gt;

&lt;p&gt;GraphQL is one door where you can order exactly what you want.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Neither approach is automatically better. They optimize for different problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  HATEOAS
&lt;/h2&gt;

&lt;p&gt;HATEOAS stands for Hypermedia as the Engine of Application State.&lt;/p&gt;

&lt;p&gt;The idea is that a response can contain information about what the client can do next.&lt;/p&gt;

&lt;p&gt;You can think of it as a kind of GPS for an API.&lt;/p&gt;

&lt;p&gt;Instead of the client having to know every possible next URL, the server provides links representing the available transitions.&lt;/p&gt;

&lt;p&gt;For example, a response could conceptually contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"_links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"self"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/orders/42"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cancel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/orders/42/cancel"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client can use the links to understand the available actions.&lt;/p&gt;

&lt;p&gt;It's a powerful idea, although it also adds complexity and isn't used by every API that calls itself RESTful.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Richardson Maturity Model
&lt;/h2&gt;

&lt;p&gt;Another useful way of thinking about APIs is the Richardson Maturity Model.&lt;/p&gt;

&lt;p&gt;It describes different levels of RESTfulness:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;Idea&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;One endpoint / one method&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;HTTP verbs and status codes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Hypermedia / HATEOAS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Level 0 is basically the "Swamp of POX": everything goes through a single endpoint, often using POST.&lt;/p&gt;

&lt;p&gt;At level 1, we start identifying resources.&lt;/p&gt;

&lt;p&gt;At level 2, we properly use HTTP methods and status codes.&lt;/p&gt;

&lt;p&gt;At level 3, hypermedia enters the picture.&lt;/p&gt;

&lt;p&gt;This was useful for me because it showed that there's a difference between:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I have an HTTP API."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I have an API that follows REST principles."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  So where does Rails fit into all of this?
&lt;/h2&gt;

&lt;p&gt;Rails gives us conventions and tools that make it very easy to build APIs following these principles.&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 ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="ss"&gt;:api&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;defaults: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;format: :json&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="ss"&gt;:v1&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:products&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this small piece of routing configuration, we're already expressing quite a lot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The API has a namespace.&lt;/li&gt;
&lt;li&gt;It has a version.&lt;/li&gt;
&lt;li&gt;It expects JSON.&lt;/li&gt;
&lt;li&gt;Products are modeled as resources.&lt;/li&gt;
&lt;li&gt;Standard HTTP verbs map to standard CRUD actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that's probably the biggest thing I took away from revisiting all of this.&lt;/p&gt;

&lt;p&gt;Rails makes a lot of these concepts feel automatic.&lt;/p&gt;

&lt;p&gt;But "automatic" doesn't mean "unimportant."&lt;/p&gt;

&lt;p&gt;Understanding what Rails is doing underneath the conventions makes it much easier to design APIs intentionally instead of just following patterns because that's what Rails usually does.&lt;/p&gt;

&lt;p&gt;And I think that's one of the differences between &lt;strong&gt;knowing Rails&lt;/strong&gt; and &lt;strong&gt;understanding what you're building with Rails&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;These are my notes from revisiting Rails routing, HTTP and REST fundamentals. There are definitely deeper rabbit holes here, especially around REST constraints, idempotency, caching and HATEOAS—but understanding these fundamentals already makes the day-to-day work with APIs much less mysterious.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>api</category>
      <category>restapi</category>
    </item>
    <item>
      <title>How to Set Up Solargraph in VS Code with WSL2</title>
      <dc:creator>Lucas Luan de Melo</dc:creator>
      <pubDate>Fri, 21 Jun 2024 12:49:32 +0000</pubDate>
      <link>https://dev.to/lucasldemello/how-to-set-up-solargraph-in-vs-code-with-wsl2-283b</link>
      <guid>https://dev.to/lucasldemello/how-to-set-up-solargraph-in-vs-code-with-wsl2-283b</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Recently, I faced an issue while trying to set up Solargraph in VS Code using WSL2 and ASDF for managing Ruby versions. The legacy projects I was working on used Docker, causing conflicts with Ruby versions and resulting in errors when initializing the server. After much research and trial and error, I managed to solve the problem. Here is a step-by-step guide to help other developers who might be facing the same issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;The easiest way to resolve Ruby version issues would be to modify the project's &lt;code&gt;.tool-versions&lt;/code&gt; file to use a Ruby version compatible with Solargraph. However, in legacy environments, this modification may not be possible due to specific project dependencies or restrictions imposed by the development team. Therefore, this guide provides an alternative solution that does not require changes to the &lt;code&gt;.tool-versions&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step-by-Step Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;WSL2 installed&lt;/strong&gt;: Follow the &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install"&gt;official Microsoft instructions&lt;/a&gt; to set up WSL2.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;VS Code installed&lt;/strong&gt;: Download and install &lt;a href="https://code.visualstudio.com/"&gt;VS Code&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Linux distribution on WSL2&lt;/strong&gt;: For example, Ubuntu.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 1: Set Up Ruby on WSL2 with ASDF
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install ASDF&lt;/strong&gt;: In the WSL2 terminal, run the following commands:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.10.0&lt;br&gt;
echo '. $HOME/.asdf/asdf.sh' &amp;gt;&amp;gt; ~/.bashrc&lt;br&gt;
echo '. $HOME/.asdf/completions/asdf.bash' &amp;gt;&amp;gt; ~/.bashrc&lt;br&gt;
source ~/.bashrc&lt;/code&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add the Ruby plugin and install a Ruby version&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;asdf plugin-add ruby https://github.com/asdf-vm/asdf-ruby.git&lt;br&gt;
asdf install ruby 3.3.2  # Replace with the necessary version&lt;br&gt;
asdf global ruby 3.3.2&lt;/code&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Verify the Ruby installation&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ruby -v&lt;/code&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Install Solargraph
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install Solargraph&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gem install solargraph&lt;/code&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Verify the Solargraph installation&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;which solargraph&lt;/code&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 3: Configure VS Code to Use WSL2
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install the "Remote - WSL" Extension&lt;/strong&gt;: In VS Code, open the Extensions Marketplace and install the &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl"&gt;Remote - WSL&lt;/a&gt; extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Open VS Code in WSL2&lt;/strong&gt;: In the WSL2 terminal, navigate to your project directory and open VS Code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;code .&lt;/code&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 4: Configure Solargraph in VS Code
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add the configuration in &lt;code&gt;settings.json&lt;/code&gt;&lt;/strong&gt;: In VS Code opened in the WSL2 environment, open the Command Palette (&lt;code&gt;Ctrl+Shift+P&lt;/code&gt; or &lt;code&gt;Cmd+Shift+P&lt;/code&gt;), search for "Preferences: Open Settings (JSON)" and add the following configuration:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"solargraph.commandPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/home/your_user/.asdf/shims/solargraph"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"solargraph.useBundler"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"solargraph.diagnostics"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"solargraph.formatting"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Replace &lt;code&gt;/home/your_user/.asdf/shims/solargraph&lt;/code&gt; with the path returned by the &lt;code&gt;which solargraph&lt;/code&gt; command.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Restart VS Code&lt;/strong&gt;: Restart VS Code to apply the new settings.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Troubleshooting
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Check permissions and paths&lt;/strong&gt;: Ensure that the path specified for Solargraph in &lt;code&gt;settings.json&lt;/code&gt; is correct and accessible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;VS Code Logs&lt;/strong&gt;: Check the VS Code logs for more details on the error. Access the logs through the Command Palette (&lt;code&gt;Ctrl+Shift+P&lt;/code&gt; -&amp;gt; "Output") and select "Solargraph" from the output menu.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With these steps, you should be able to set up Solargraph in VS Code using the Ruby version managed by ASDF in the WSL2 environment, without the need to modify the project's &lt;code&gt;.tool-versions&lt;/code&gt; file. I hope this guide helps solve similar issues you might encounter in your Ruby development environment.&lt;/p&gt;




&lt;p&gt;I hope this guide has been helpful! If you have any questions or suggestions, leave a comment below. 🚀&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>ruby</category>
      <category>productivity</category>
      <category>solargraph</category>
    </item>
    <item>
      <title>Como Configurar o Solargraph no VS Code com WSL2 para projetos legados</title>
      <dc:creator>Lucas Luan de Melo</dc:creator>
      <pubDate>Fri, 21 Jun 2024 12:38:56 +0000</pubDate>
      <link>https://dev.to/lucasldemello/como-configurar-o-solargraph-no-vs-code-com-wsl2-para-projetos-legados-2eg8</link>
      <guid>https://dev.to/lucasldemello/como-configurar-o-solargraph-no-vs-code-com-wsl2-para-projetos-legados-2eg8</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Recentemente, enfrentei um problema ao tentar configurar o Solargraph no VS Code enquanto utilizava o WSL2 e o ASDF para gerenciar versões do Ruby. Os projetos legados que eu estava trabalhando usavam Docker, o que causava conflitos com as versões do Ruby e resultava em erros ao inicializar o servidor. Após muita pesquisa e tentativa e erro, consegui resolver o problema. Aqui está um guia passo a passo para ajudar outros desenvolvedores que possam estar enfrentando a mesma situação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;O caminho mais fácil para resolver problemas de versão de Ruby seria modificar o arquivo &lt;code&gt;.tool-versions&lt;/code&gt; do projeto para usar uma versão do Ruby compatível com o Solargraph. No entanto, em ambientes legados, essa modificação pode não ser possível devido a dependências específicas do projeto ou restrições impostas pela equipe de desenvolvimento. Portanto, este guia fornece uma solução alternativa que não requer mudanças no arquivo &lt;code&gt;.tool-versions&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passo a Passo para Resolver o Problema
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pré-requisitos
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;WSL2 instalado&lt;/strong&gt;: Siga as &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install"&gt;instruções oficiais da Microsoft&lt;/a&gt; para configurar o WSL2.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;VS Code instalado&lt;/strong&gt;: Baixe e instale o &lt;a href="https://code.visualstudio.com/"&gt;VS Code&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Distribuição Linux no WSL2&lt;/strong&gt;: Por exemplo, Ubuntu.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Passo 1: Configure o Ruby no WSL2 com ASDF
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Instale o ASDF&lt;/strong&gt;: 
No terminal do WSL2, execute os seguintes comandos:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    git clone https://github.com/asdf-vm/asdf.git ~/.asdf &lt;span class="nt"&gt;--branch&lt;/span&gt; v0.10.0
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'. $HOME/.asdf/asdf.sh'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'. $HOME/.asdf/completions/asdf.bash'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
    &lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Adicione o plugin Ruby e instale uma versão do Ruby&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    asdf plugin-add ruby https://github.com/asdf-vm/asdf-ruby.git
    asdf &lt;span class="nb"&gt;install &lt;/span&gt;ruby 3.3.2  &lt;span class="c"&gt;# Substitua pela versão necessária&lt;/span&gt;
    asdf global ruby 3.3.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Verifique a instalação do Ruby&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    ruby &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Passo 2: Instale o Solargraph
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Instale o Solargraph&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   gem &lt;span class="nb"&gt;install &lt;/span&gt;solargraph 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Verifique a instalação do Solargraph&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    which solargraph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Passo 3: Configure o VS Code para Usar o WSL2
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Instale a Extensão "Remote - WSL"&lt;/strong&gt;: No VS Code, abra o Marketplace de Extensões e instale a extensão &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl"&gt;Remote - WSL&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Abra o VS Code no WSL2&lt;/strong&gt;: No terminal do WSL2, navegue até o diretório do seu projeto e abra o VS Code:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Passo 4: Configure o Solargraph no VS Code
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Adicione a configuração no &lt;code&gt;settings.json&lt;/code&gt;&lt;/strong&gt;: No VS Code aberto no ambiente WSL2, abra o Command Palette (&lt;code&gt;Ctrl+Shift+P&lt;/code&gt; ou &lt;code&gt;Cmd+Shift+P&lt;/code&gt;), procure por "Preferences: Open Settings (JSON)" e adicione a seguinte configuração:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"solargraph.commandPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/home/seu_usuario/.asdf/shims/solargraph"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"solargraph.useBundler"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"solargraph.diagnostics"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"solargraph.formatting"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Substitua &lt;code&gt;/home/seu_usuario/.asdf/shims/solargraph&lt;/code&gt; pelo caminho retornado pelo comando &lt;code&gt;which solargraph&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reinicie o VS Code&lt;/strong&gt;: Reinicie o VS Code para aplicar as novas configurações.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Solução de Problemas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verifique as permissões e caminhos&lt;/strong&gt;: Certifique-se de que o caminho especificado para o Solargraph no &lt;code&gt;settings.json&lt;/code&gt; está correto e acessível.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Logs do VS Code&lt;/strong&gt;: Verifique os logs do VS Code para mais detalhes sobre o erro. Acesse os logs através do Command Palette (&lt;code&gt;Ctrl+Shift+P&lt;/code&gt; -&amp;gt; "Output") e selecione "Solargraph" no menu de saída.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;Com esses passos, você deve conseguir configurar o Solargraph no VS Code utilizando a versão do Ruby gerenciada pelo ASDF no ambiente WSL2, sem a necessidade de modificar o arquivo &lt;code&gt;.tool-versions&lt;/code&gt; do projeto. Espero que este guia seja útil para resolver problemas semelhantes que você possa encontrar no seu ambiente de desenvolvimento Ruby.&lt;/p&gt;

</description>
      <category>solargraph</category>
      <category>vscode</category>
      <category>ruby</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
