<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="130535" data-post-id="130535">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="chulkilee" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chulkilee/120/6207_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  chulkilee
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="jeremyjh" data-post="11" data-topic="22810">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jeremyjh/48/5995_2.png" class="avatar"> jeremyjh:</div>
<blockquote>
<p>Well…that is just sad, lazy design. I’m not sure people who would do that, would do much better just because they use a different tool.</p>
</blockquote>
</aside>
<p>Pick any REST API, and you’ll see such problems in different ways. e.g. <a href="https://developer.github.com/v3/orgs/#get-an-organization" rel="noopener nofollow ugc">GitHub API v3 organization</a> has <code>plan</code> as object attribute while many other count/stats or policy related attributes right under the organization resource.</p>
<p>Also.. sometimes we don’t know what would change - or we may underestimate size or impact of changes (compared to initial cost). There are many reasons other than being “lazy” to end up with such APIs.</p>
<aside class="quote no-group" data-username="Exadra37" data-post="10" data-topic="22810">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/exadra37/48/9183_2.png" class="avatar"> Exadra37:</div>
<blockquote>
<p>By using API first design approach, with the uses of tools like <a href="https://raml.org/" rel="noopener nofollow ugc">RAML</a> or <a href="https://swagger.io/" rel="noopener nofollow ugc">OpenAPI</a>, than you are forced to think ahead in the design of your API and avoid lots of pitfalls, because if before you start coding you share your full API specification with who will consume it, then you will receive feedback, and changes will need to be made to the specification, and rinse and repeat until everyone is in consensus with the spec, and now is the time to start coding, but even after you start coding you will still find areas to improve, thus you will need to stop coding and go back to the cycle of changing the spec, share it, receive feedback, and optimize the spec until everyone is in consensus.</p>
</blockquote>
</aside>
<p>I agree that this makes overall design much much better.</p>
<p>However..</p>
<ul>
<li>There are fundamental tension
<ul>
<li>API is more of “consuming”, not “exposing”</li>
<li>REST API aims to “reusable”, consistent resource, which should be “generic” interface.</li>
</ul>
</li>
<li>RAML / OpenAPI is just a tool to convey API spec, so it helps communication between interested parties… but it does not provide any guidance which is “better” way.</li>
<li>Everyone need to understand REST API philosophy but anyway it will end up with different output.</li>
</ul>
<p>For example, it reminds me of debating on code style. Luckily we can reformat code easily… but API style is not. e.g. Changing JSON:API into something different spec requires huge amount of dev work.</p>
<hr>
<p>After working with many APIs (on both server/client sides), I prefer to pick up existing sub-optimal but clear, opinionated rule with great tooling supports rather than creating my own rule which perfectly support all my problems. I really wish there would be such things in REST API.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="130535" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/what-s-your-worst-experience-with-a-rest-api/22810/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-130535" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="130535"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="130543" data-post-id="130543">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="chriseyre" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chriseyre/120/11497_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  chriseyre
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The worst that I have seen is one that takes a string and returns a string.</p>
<p>The strings are internally converted into xml/json, do work and return a result.</p>
<p>Reimplementing these can require understanding the entire system behind the API</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="130543" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/what-s-your-worst-experience-with-a-rest-api/22810/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-130543" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="130543"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="130562" data-post-id="130562">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lucaong" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lucaong/120/21794_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lucaong
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="peerreynders" data-post="4" data-topic="22810">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/48/5826_2.png" class="avatar"> peerreynders:</div>
<blockquote>
<p>There is no restriction to publishing resources that aggregate other resources to save the number of requests that you have to make.</p>
</blockquote>
</aside>
<p>thanks <a class="mention" href="/u/peerreynders" rel="nofollow">@peerreynders</a> for your sharing your well argued view. I might have explained myself wrong though: my point was not to argue that REST does not work in some context. The original question was about personal bad experiences with REST APIs, and my example was that of separate client application development and API development teams, and the friction created by diverging goals.</p>
<p>There is no doubt that it is possible to structure a REST API in a way that serves the needs of a client application perfectly. My point is more about the <em>relative effort</em> of building an API that serves the need of a client application. Not only factoring in coding effort for the API developers, but also the communication and design effort with client application developers, chances of misunderstanding and frustration, etc.</p>
<p>The relevant difference between REST and GraphQL in this case is not whether an aggregate resource is possible or not, but rather about who makes which decision about the aggregate. In the specific case of a client application (think a mobile app) fetching data from an internal API, one typically has the situation that:</p>
<ul>
<li>The API developers know best how to produce data</li>
<li>The client application developers know best what data is needed where</li>
</ul>
<p>GraphQL, in this case, leaves these decisions to the side that has the most knowledge. A REST API must either expose an aggregate “decided” by the API, or expose multiple small endpoints, leaving the choice of what to fetch to the client developers, but also the burden of orchestrating a graph of dependent queries. No doubt that a very good team can design the perfect REST API too. It’s just more effort in this case, especially if client and API developers are different people/teams.</p>
<aside class="quote no-group" data-username="peerreynders" data-post="4" data-topic="22810">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/48/5826_2.png" class="avatar"> peerreynders:</div>
<blockquote>
<p>As far as I can tell GraphQL APIs can suffer the same sort of versioning problems.</p>
</blockquote>
</aside>
<p>True. I say that GraphQL <em>alleviates</em> the API versioning problem, but I am not arguing that versioning problem is completely removed. My view is that in this specific case GraphQL leads to fewer decisions that have to be made cross-team, and the higher flexibility from the client application side <em>can</em> lead to a lower chance of having to introduce backward incompatible changes (but again, depending on team, situation, trade-offs, etc.).</p>
<p>Finally, I am definitely not arguing against REST APIs in general. REST is a well-proven way of structuring APIs, and I hope I made it clear how I think it makes other problems simpler (caching, updates, etc.). Mine is a personal experience, and applies to the specific situation of separate API and client application teams.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="130562" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/what-s-your-worst-experience-with-a-rest-api/22810/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-130562" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="130562"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="130574" data-post-id="130574">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="peerreynders" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/120/5826_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  peerreynders
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<blockquote>
<p>Not only factoring in coding effort for the API developers, but also the communication and design effort with client application developers, chances of misunderstanding and frustration, etc.</p>
</blockquote>
<p>One thing that comes across in <a href="https://youtu.be/pJamhW2xPYw" rel="noopener nofollow ugc">Marc-André Giroux’s talk</a> is that communication between developers on the integrator and provider side is key in order to evolve an effective schema. So regardless what technology is employed, communication difficulties can only have a negative impact the quality of the API.</p>
<blockquote>
<p>but rather about who makes which decision about the aggregate.</p>
</blockquote>
<p>The provider team working in a vacuum without input from the consumers isn’t likely going to result in an effective API regardless of technology.</p>
<blockquote>
<p>GraphQL, in this case, leaves these decisions to the side that has the most knowledge.</p>
</blockquote>
<p>The provider side <em>should</em> have the most knowledge about their domain. That doesn’t necessarily imply that they fully comprehend the needs of their consumers.</p>
<blockquote>
<p>My view is that in this specific case GraphQL leads to fewer decisions that have to be made cross-team</p>
</blockquote>
<p>The anecdotal evidence I’ve come across over the years is that these types of problems are not best solved with technology but with <em>cross-functional teams</em> - i.e. the same people who consume the API also design it.</p>
<hr>
<p>Marc-André Giroux <a href="https://medium.com/@__xuorig__/where-we-come-from-an-honest-introduction-to-graphql-4a2ef6124488" rel="noopener nofollow ugc">published</a> an introductory chapter of his upcoming book.</p>
<p>His hypothesis is that REST APIs ran into trouble because of OSFA (one size fits all) design. In the ideal case a REST API would just represent the domain in terms of resources but the consequence was that the API would be equally inconvenient for most consumers. Adding more resources to accommodate different consumers needs, only serve to make the API convoluted.</p>
<p>In response to the problem Soundcloud started to segregate these resources into separate BFFs.</p>
<p>I find the <a href="https://medium.com/netflix-techblog/embracing-the-differences-inside-the-netflix-api-redesign-15fd8b3dc49d" rel="noopener nofollow ugc">approach that Netflix took</a> to be the most interesting.</p>
<p>They arranged for consumers to deploy <em>server-side client adapters</em>. That way the general API can be <em>just</em> domain oriented while the server-side client adapter can focus on the needs of <em>one</em> particular client managing lean payloads with an optimal shape for the client on the other side of the network.</p>
<p>Marc-André Giroux views client-side GraphQL as a “client-side BFF”. So just like a normal BFF is coupled to the general server-side API, client-side GraphQL is coupled to the provider schema.</p>
<p>In order to provide this sort of flexibility on the client-side I think that GraphQL has increased the end-to-end <a href="https://www.freecodecamp.org/news/five-common-problems-in-graphql-apps-and-how-to-fix-them-ac74d37a293c/" rel="noopener nofollow ugc">accidental complexity</a>.</p>
<p>While “client-side BFF” can work, I have to wonder whether with the emergence of <a href="https://medium.com/@addyosmani/the-cost-of-javascript-in-2018-7d8950fbb5d4" rel="noopener nofollow ugc">JS budgets</a> to accomodate the anticipated increase in consumption of the web via lower end smart devices there is going to be a push for even leaner client-to-server interactions - where the content <em>and</em> shape of the data is customized to a fit specific clients needs in order to minimize the amount of code and processing time that is needed on the client.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="130574" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/what-s-your-worst-experience-with-a-rest-api/22810/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-130574" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="130574"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="130613" data-post-id="130613">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="balas" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/balas/120/10323_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  balas
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>If you make your API too fine-grained then REST will necessitate too many calls. We can also send nested and related entities in REST. GraphQL is mostly providing the data needed by the client where all requests posted to a single URL and request data in a payload. Hinders readability if the QLs are kept in a different file. REST URLs is more readable. People can make both worse. I worked on a project where somebody who was new to all these REST stuff 7 years ago. He had a URL for updating every field of an entity (More readable but too fine-grained and violated REST itself).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="130613" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/what-s-your-worst-experience-with-a-rest-api/22810/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-130613" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="130613"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>