<?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: Peter Nycander</title>
    <description>The latest articles on DEV Community by Peter Nycander (@peternycander).</description>
    <link>https://dev.to/peternycander</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F87612%2F354a5419-ac09-4b15-87ac-30d7dc2bb0e7.jpg</url>
      <title>DEV Community: Peter Nycander</title>
      <link>https://dev.to/peternycander</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/peternycander"/>
    <language>en</language>
    <item>
      <title>Almost 4 Years in - Common GraphQL design mistakes I've seen</title>
      <dc:creator>Peter Nycander</dc:creator>
      <pubDate>Wed, 15 Dec 2021 18:41:43 +0000</pubDate>
      <link>https://dev.to/peternycander/common-graphql-design-mistakes-npi</link>
      <guid>https://dev.to/peternycander/common-graphql-design-mistakes-npi</guid>
      <description>&lt;p&gt;When I have consulted companies implementing GraphQL I tend to see the same design mistakes pop up quite often. This article will go through a few of the lessons I have learned after almost four years of GraphQL design, so that you don't have to repeat those mistakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding the field &lt;code&gt;type: String&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This might not seem obvious to everyone that this is a mistake, but it is a clear code smell. GraphQL is based around its typesystem, so using &lt;code&gt;type: String&lt;/code&gt; instead of the built-in &lt;code&gt;__typename&lt;/code&gt; just does not take advantage of that fact. What you want in most cases is an interface. Each possible value of &lt;code&gt;type: String&lt;/code&gt; gets its own GraphQL type which implements that interface.&lt;/p&gt;

&lt;p&gt;This will allow you to make a smarter schema, because odds are that not every field is shared among all the different types. Another benefit is that reading the schema will hint to the consumer what possible values to expect. The hinting can be achieved with an enum, but there is little to no downside to using the interface instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mirroring the backend models
&lt;/h2&gt;

&lt;p&gt;It is quite easy when starting with GraphQL to just expose all the fields that you get from the backend services or database models. The point of GraphQL is to let clients pick and choose from the data, right? Well kind of, but you should think before exposing too much data.&lt;/p&gt;

&lt;p&gt;The best way is usually to go client first. Ask yourself the question: What do the consuming clients actually need? It could be that you have a &lt;code&gt;Country&lt;/code&gt; object with fields such as &lt;code&gt;countryCode&lt;/code&gt;, &lt;code&gt;fullName&lt;/code&gt;, &lt;code&gt;currency&lt;/code&gt; etc, but all the frontend needed was the url and alt text to a flag of that country. The client would probably have to look at &lt;code&gt;countryCode&lt;/code&gt; to generate a url, and hope they always match, and concatenate &lt;code&gt;fullName&lt;/code&gt; with some other string to build the alt text.&lt;/p&gt;

&lt;p&gt;This way of designing is often referred to as a demand-oriented schema. Demand-oriented schema design deserves its own article, because it is a fascinating subject. But the big reasons to use it is that 1. You will design a schema more aligned with the product rather than the database, and 2. this will decouple your database design from your GraphQL schema (which might useful when you change database design later on).&lt;/p&gt;

&lt;h2&gt;
  
  
  Limiting the API to suit your caching requirements
&lt;/h2&gt;

&lt;p&gt;A normal way to deal with high volumes of traffic is to cache requests using HTTP caching, which can be leveraged in browsers and CDNs (Content Delivery Networks). To get a decent cache hit ratio you need to make sure that the resources are the same for every user. You would not want the request to get the users avatar or username to get cached and being served to the wrong user!&lt;/p&gt;

&lt;p&gt;GraphQL is most commonly used through HTTP POST requests, which are usually not cached. However there are ways to send GraphQL requests using HTTP GET, either with the full query string or using persisted queries.&lt;/p&gt;

&lt;p&gt;In a typical GraphQL schema you usually have a mix of private and public data. The public data is cachable, but the private is not. This creates a problem if you want to leverage HTTP caching. You can really only cache fully public data.&lt;/p&gt;

&lt;p&gt;Optimizing for cache hits would however lead to trying to reuse the same exact query in multiple places, and instead of having private data like &lt;code&gt;progressPercentage: Float&lt;/code&gt; of a &lt;code&gt;type Movie&lt;/code&gt; you would have to have a separate query to get the progress, and try to stitch the data together after the fact. This is what we are used to doing with REST apis, and we are really not getting the full benefits of GraphQL by doing this.&lt;/p&gt;

&lt;p&gt;I would recommend going as long as you can with just using caching inside of your server logic using something like redis, and only consider HTTP caching as a last resort when designing your GraphQL api.&lt;/p&gt;




&lt;p&gt;If you liked this article, I have a few more design mistakes listed in the original article at: &lt;a href="https://www.hubburu.com/articles/common_graphql_design_mistakes"&gt;https://www.hubburu.com/articles/common_graphql_design_mistakes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>graphql</category>
    </item>
    <item>
      <title>Using the big O notation in the wild</title>
      <dc:creator>Peter Nycander</dc:creator>
      <pubDate>Sat, 15 Jun 2019 11:25:48 +0000</pubDate>
      <link>https://dev.to/peternycander/using-the-big-o-notation-in-the-wild-200d</link>
      <guid>https://dev.to/peternycander/using-the-big-o-notation-in-the-wild-200d</guid>
      <description>&lt;p&gt;I see a lot of people getting scared by the big O notation, and I get it. It is a math thing, and math is scary for a lot of people.&lt;/p&gt;

&lt;p&gt;I have a masters degree in Computer Science, and truth be told, the first year or so the big O notation was very scary for me too. But for each year of professors talking about it, it got less scary.&lt;/p&gt;

&lt;p&gt;In the "wild", that knowledge has turned out to be useless in the vast majority of the day-to-day work. But there is one pattern that I've seen repeated by a lot of people, which has the potential to make server response times and load worse than it they had to be if they had known a simple trick tied to the big O notation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scenario
&lt;/h2&gt;

&lt;p&gt;Imagine the follow scenario; you have two different services you are integrating with. They both return a list of people. One only has data about which vocation the person has, and one only has the name of the person. You want to combine these to a single list. In this scenario, they share an id, but the list is not sorted.&lt;/p&gt;

&lt;p&gt;The pattern that I've observed is to loop through one of the lists, and in that loop try to &lt;code&gt;.find&lt;/code&gt; the corresponding item in the second list. It works, and makes a lot of sense when you read it. It also has a worse time complexity (the thing big O "measures") than it could have had.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analyzing the time complexity
&lt;/h3&gt;

&lt;p&gt;What big O notation means is when the number of people in the list increases, how does that affect the running time? (or memory, but lets focus on time). It also is only concerned with the worst possible case, that is maximum bad luck with how the list is sorted.&lt;/p&gt;

&lt;p&gt;In our case, for every person in the list, we will have to potentially look at every other person in the other list to pair them together. Lets call the number of people in the list &lt;code&gt;n&lt;/code&gt;, which is the (stupid?) norm. In order to create &lt;em&gt;one&lt;/em&gt; complete person we would have to potentially look at &lt;code&gt;n&lt;/code&gt; items in a list by using &lt;code&gt;.find&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This work has to be repeated for all &lt;code&gt;n&lt;/code&gt; persons. That means the time complexity will be &lt;code&gt;O(n*n)&lt;/code&gt; or &lt;code&gt;O(n^2)&lt;/code&gt;. We can do a lot better.&lt;/p&gt;

&lt;h3&gt;
  
  
  The easy fix
&lt;/h3&gt;

&lt;p&gt;The thing we can make faster is finding the corresponding person in the other list. In javascript, we can use a simple object &lt;code&gt;{}&lt;/code&gt; for this. In other languages you should look for something called &lt;code&gt;Map&lt;/code&gt; or &lt;code&gt;dict&lt;/code&gt; or similar.&lt;/p&gt;

&lt;p&gt;What you want to do is some prework to create a lookup object where you can get the name object if you have the id. It would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lookup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;13&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Robert&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;13&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;52&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Julia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;52&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That way, instead of using &lt;code&gt;.find&lt;/code&gt; to get the name, you can do &lt;code&gt;lookup[id]&lt;/code&gt;. The benefit is that getting a value from an object is, through the magic of computers, super fast. In fact, when we talk about it in big O notation we don't even take note of it. It is said to take constant time. What it means is that is does not matter if the object has 100 or 10000 items in it, it takes about the same time to fetch the item.&lt;/p&gt;

&lt;p&gt;If you don't take my word for it, I made a &lt;a href="https://codepen.io/peternycander/pen/orbdvO"&gt;codepen for you to look at&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The time complexity of the fix
&lt;/h3&gt;

&lt;p&gt;Since the &lt;code&gt;lookup[id]&lt;/code&gt; takes constant time, we don't count it in big O notation. That means for we still have to look at each person one time, and for that person we only do constant work. That means we are down to &lt;code&gt;O(n)&lt;/code&gt;. That is a great time complexity for most problems, and it is the best we can do in this case.&lt;/p&gt;

&lt;p&gt;However, we have the added work of the prework. We actually loop through the list twice. That is &lt;code&gt;O(2*n)&lt;/code&gt;, but a weird thing about the big O notation is that we simply remove any constant numbers. So that means that &lt;code&gt;O(2*n) = O(n)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That weirdness is due to the fact that the big O notation does not actually translate to how long an algorithm takes. It only translates to the order of magnitude of the time increase when the input size increases.&lt;/p&gt;




&lt;p&gt;Time complexity is rarely important in day-to-day work, but it does come up once in a while. What you can take with you from this article is that as soon as you see a loop inside of another loop, you might be looking at code with bad time complexity. Think through if it matters, and if you can use the trick above to fix it.&lt;/p&gt;

</description>
      <category>computerscience</category>
    </item>
    <item>
      <title>Why you should not (only) do mob programming</title>
      <dc:creator>Peter Nycander</dc:creator>
      <pubDate>Fri, 14 Jun 2019 17:48:05 +0000</pubDate>
      <link>https://dev.to/peternycander/why-you-should-not-only-do-mob-programming-4jo9</link>
      <guid>https://dev.to/peternycander/why-you-should-not-only-do-mob-programming-4jo9</guid>
      <description>&lt;p&gt;I have been exposed and tried a lot of different forms of programming; solo, pair, small teams, big teams, remote teams, teams across companies and, the topic of this article, mob programming.&lt;/p&gt;

&lt;p&gt;Mob programming is when an entire team is programming on a single computer – one keyboard, one mouse, 3-7 (or more?) people. A mob does not have to consist of only developers; a mob can consist of one designer, one product owner, and two web developers.&lt;/p&gt;

&lt;p&gt;While I am a little provocative in my choice of title and implying that mob programming is bad – it is not the entire truth about how I feel. Mob programming &lt;em&gt;can&lt;/em&gt; be great. For example in aforementioned mob setup during the design implementation of the layout and user journey in the frontend of a new feature.&lt;/p&gt;

&lt;p&gt;In such a scenario; the designer can make quick tweaks to the design during development (and does not have to spend time on getting design files pixel perfect), the two web developers can solve CSS issues quicker than one could, and the product owner can make sure the customer journey is turning out as expected.&lt;/p&gt;

&lt;p&gt;The idea that I find problematic is the idea of permanent mob programming with 3-7 people with similar skill sets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some tasks are not suited to mob programming
&lt;/h2&gt;

&lt;p&gt;As developers, we are not only tasked with writing shiny new features. There is a lot of communication, debugging, refactoring, maybe some “manual” labour like configuring servers or writing documentation.&lt;/p&gt;

&lt;p&gt;The most common argument that I've heard for doing the more menial tasks in a mob is that you probably are more likely to make mistakes during the “boring” work – and a mob is more likely to catch the mistakes than one individual.&lt;/p&gt;

&lt;p&gt;This might be the case for some, but what I've found to usually happen is that one or two might be focused on the task, and others might let the mind wander. People thinking about what to eat for dinner next week do not catch subtle mistakes. At that point they could be working on something more productive which would be less mind numbing.&lt;/p&gt;

&lt;p&gt;If you know a lot about mob programming you might be sitting there, red faced with anger thinking that if he only did &lt;em&gt;true&lt;/em&gt; mob programming – with a rotating navigator and a driver then none of that would happen. Trust me, it happens anyway. Maybe not to you, dear individual, but maybe your team mates.&lt;/p&gt;

&lt;h2&gt;
  
  
  People converge
&lt;/h2&gt;

&lt;p&gt;One of the arguments for mob programming is that you are never stuck – you are so many working on the same problem at the same time. All with different knowledge sets and different backgrounds, &lt;em&gt;someone&lt;/em&gt; in the mob probably knows the solution.&lt;/p&gt;

&lt;p&gt;That might be true during your first months together. But over time, the members of the mob will transfer a lot of their knowledge to each other. The different knowledge sets and backgrounds will become less and less different.&lt;/p&gt;

&lt;p&gt;The knowledge transfer is a great thing, especially for the less experienced individuals (and the bus factor), but the total amount of knowledge and experience in the mob/team will remain almost the same. It will only grow by what happens on the mob computer. Not so great for the team in the long run.&lt;/p&gt;

&lt;h2&gt;
  
  
  It does not deliver on its promises
&lt;/h2&gt;

&lt;p&gt;It is worth reiterating that I am talking about a mob consisting of people with similar skill sets that have been working in the same mob for several months of longer. Say 4 React developers with great javascript skills and average CSS knowledge.&lt;/p&gt;

&lt;p&gt;Some promises that I have heard about mob programming that I do not think applies to these mobs are:&lt;/p&gt;

&lt;h3&gt;
  
  
  Fewer mistakes
&lt;/h3&gt;

&lt;p&gt;This is highly dependant on the individuals, but what I found very common is that if some senior developer with a lot of respect makes a mistake – chances are it might not get caught. We are social creatures, and calling out someone who carries a lot of respect is hard. Your level of certainty about the mistake will have to be quite high.&lt;/p&gt;

&lt;p&gt;Another factor that plays in is &lt;a href="https://en.wikipedia.org/wiki/Groupthink"&gt;groupthink&lt;/a&gt;. It is not a positive term, and can become a real issue when you have worked together for a while. It essentially reduces critical evaluation of ideas. When you have managed to converge your mob into a cosy unit you possibly removed the benefit of fewer mistakes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Work always continues
&lt;/h3&gt;

&lt;p&gt;Mob programming is said to always continue, even when someone has to go to a meeting or is home sick. While this is often true (one exception is team/company-wide meetings), you are exposing the work to another fault of us humans: &lt;a href="https://en.wikipedia.org/wiki/Diffusion_of_responsibility#Social_loafing"&gt;diffusion of responsibility&lt;/a&gt;. The gist of it is that in a group setting you are less likely to take action or responsibility yourself.&lt;/p&gt;

&lt;p&gt;Say you side tracked to talking about travelling or something else non work-related. During that time you probably don't feel as bad as if you side tracked yourself, looking up private travel plans on company time. My guess is that the mob version also lasts longer as long as the surrounding environment allows it.&lt;/p&gt;

&lt;p&gt;Another factor is that any break you need to take have a tendency to escalate to the entire mob. How long breaks people need and how far between they have to between is very individual. If the person with the loudest voice needs more and longer breaks than the average team member then the net output is lower than it could have been.&lt;/p&gt;

&lt;h3&gt;
  
  
  Communication is fast
&lt;/h3&gt;

&lt;p&gt;You can communicate in the mob quite fast – as it is essentially an eternal meeting. That could be a great tool to avoid blocking questions to stake holders, but not so in the mob of similarly skilled developers.&lt;/p&gt;

&lt;p&gt;The blocking communication between developers tend to be either architectural in nature, or in form of code reviews. In case of architecture discussions; I don't know about you, but those discussions do not happen every day for me. When they do happen, gathering around a whiteboard is usually not that hard.&lt;/p&gt;

&lt;p&gt;Code reviews in mob programming are fast though, and I won't argue against that. However, I would argue that the effectiveness of the code review is reduced. That is because you all were part of the same train of thought that lead you to the solution. There might be a simpler way of solving the problem that someone with fresh pair of eyes would have found.&lt;/p&gt;




&lt;p&gt;Mob programming can be a great tool, but is not a great default way to work. I think that any mob should be short lived to minimize group think.&lt;/p&gt;

&lt;p&gt;I also feel that in order to gain the most value of the communication benefit, that they should contain people with different skill sets and different responsibilities. All of those skill sets need to be relevant to the development of the feature in progress. I've been in mobs with backend developers for pure frontend work.&lt;/p&gt;

&lt;p&gt;I think that the early success of trying mob programming might lure some teams into committing to it long term. I think that decision can have a negative impact on your work without you even noticing.&lt;/p&gt;

&lt;p&gt;If mob programming in the setup I have talked about works for you, great. Hopefully I helped you see some potential pitfalls which might occur in new teams though.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>workplace</category>
      <category>productivity</category>
    </item>
    <item>
      <title>HOWTO: Adopting GraphQL in an existing project</title>
      <dc:creator>Peter Nycander</dc:creator>
      <pubDate>Mon, 10 Jun 2019 07:16:26 +0000</pubDate>
      <link>https://dev.to/peternycander/how-i-would-adopt-graphql-in-a-brownfield-project-ap8</link>
      <guid>https://dev.to/peternycander/how-i-would-adopt-graphql-in-a-brownfield-project-ap8</guid>
      <description>&lt;p&gt;I recently wrote about my &lt;a href="https://dev.to/peternycander/a-year-of-large-scale-graphql-the-biggest-takeaways-3d5n"&gt;experiences with large scale GraphQL at C More&lt;/a&gt;. Since I am sold on the concept of GraphQL, I have been thinking about how I would approach implementing it in a another brownfield project – all over again. So these are my tips to anyone looking into implementing GraphQL in a brownfield project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get more developers excited
&lt;/h2&gt;

&lt;p&gt;Of course this only applies if you are working in a larger organization, but I think the first step should be to get other developers excited.&lt;/p&gt;

&lt;p&gt;If you are going to create and maintain a great schema design, you need to know a lot about all the clients needs. If you work only in javascript, you probably lack some insight in how android or iOS clients actually work with GraphQL – for example; what is the experience like for them if you introduce a new type in a union of a response? You will need help from the developers who work with these platforms in order to understand their needs.&lt;/p&gt;

&lt;p&gt;As developers we often have the power to actually make things happen, and if you are like me, you work a lot harder and faster when you are excited about something. If you have developers in other teams who are excited and advocates for GraphQL, you are more likely to have success in your implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design with pen and paper
&lt;/h2&gt;

&lt;p&gt;Don't start by writing code! It will become very easy to repeat some of the mistakes I mentioned in my &lt;a href="https://dev.to/peternycander/a-year-of-large-scale-graphql-the-biggest-takeaways-3d5n"&gt;earlier post&lt;/a&gt;. Start instead by mapping out the data needs of the clients, and in what way it makes most sense for that data to be connected.&lt;/p&gt;

&lt;p&gt;What should the root queries be, and what is better suited to be a field on another type? What should be an interface and what should be a union? What should the mutations return; will it be possible to resolve all mutated data from that response? I realize this might be extremely hard without experience with GraphQL, but do your best. Don't think too much about what the backend APIs are like when designing the schema, I think that GraphQL should be all about making it easy for the clients.&lt;/p&gt;

&lt;p&gt;I'm not suggesting that you run this like a waterfall project, but in my experience a mistake in design is far more costly than taking a day to really get to know your domain and how GraphQL fits into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the most isolated parts of the design
&lt;/h2&gt;

&lt;p&gt;It is tempting to implement the core features of your product right away with GraphQL. However, those are the most painful parts to get wrong – and you will get things wrong. Instead, find some feature which won't be &lt;em&gt;too&lt;/em&gt; connected to the rest of the graph. Implement it all the way and out to production, hopefully across different clients.&lt;/p&gt;

&lt;p&gt;This will give you insights which will be valuable when you implement the more important parts. You will start to get get answers to questions like;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did you even like GraphQL?&lt;/li&gt;
&lt;li&gt;How did your hosting solution work for you?&lt;/li&gt;
&lt;li&gt;Do you need caching on the GraphQL server?&lt;/li&gt;
&lt;li&gt;What should the caching strategy look like (HTTP, CDN, in-memory, Redis, normalize data or not)?&lt;/li&gt;
&lt;li&gt;Were you happy with how you did error handling?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fix your mistakes early on
&lt;/h2&gt;

&lt;p&gt;As I said, you will get things wrong. It is a lot better to detect a mistake after implementing it once or twice rather than 20 or 30 times. In my experience, bad patterns have a way of multiplying once they are in a code base. More junior developers will see existing code as a template on how to implement features, and the mistakes will spread.&lt;/p&gt;

&lt;p&gt;As to how you correct the mistakes – note that GraphQL is unversioned 😱. You need to create a new field with a new name in order to make breaking changes to that field (remember to talk to other teams to learn what is breaking changes for them). It is tempting to try to come up with an even better name than last time, but when you are creating the fourth synonym in the same schema it's starting to feel silly.&lt;/p&gt;

&lt;p&gt;What I feel is the more pragmatic and logical naming convention is to just append "Two" or "2" after the name. The clients can &lt;a href="https://graphql.org/learn/queries/#aliases"&gt;alias&lt;/a&gt; this field in their query to keep the old name in their code. Once no one is using the original name, you can deprecate the "Two"-version and go back to the original name with the new type definitions. The migration for the clients should hopefully be to just remove the alias at that point. Using the append-number naming convention hopefully makes it obvious why there are two very similar fields – the first one had mistakes in it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the pace and monitor GraphQL usage
&lt;/h2&gt;

&lt;p&gt;Keep at it – implement all new features with GraphQL and use potential downtime to move old features to GraphQL.&lt;/p&gt;

&lt;p&gt;It is also a good idea to have some monitoring of your GraphQL server. What queries are slow, why? Which queries and fields are being used, and by which clients? Make sure all clients send some metadata about who they are like version numbers and platform name. Find a product which solves this for your GraphQL server, or create your own.&lt;/p&gt;




&lt;p&gt;I have not mentioned any specific technology here – and that is because I don't think it really matters that much. I suggest you use whatever library seems best supported in a language which won't be an obstacle in itself.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>brownfield</category>
      <category>legacy</category>
    </item>
    <item>
      <title>A year of large scale GraphQL - the biggest takeaways</title>
      <dc:creator>Peter Nycander</dc:creator>
      <pubDate>Sat, 01 Jun 2019 18:27:05 +0000</pubDate>
      <link>https://dev.to/peternycander/a-year-of-large-scale-graphql-the-biggest-takeaways-3d5n</link>
      <guid>https://dev.to/peternycander/a-year-of-large-scale-graphql-the-biggest-takeaways-3d5n</guid>
      <description>&lt;p&gt;GraphQL has been around for quite a while now, and it has been a hot topic as a possible candidate for the next generation of data fetching.&lt;/p&gt;

&lt;p&gt;I have been working with large scale GraphQL for over a year now, mainly for the nordic subcription video on demand (SVOD) service C More. I had never touched GraphQL before this, so I thought my experience during this time could be valuable for folks early in their GraphQL journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is GraphQL
&lt;/h2&gt;

&lt;p&gt;GraphQL is a query language, in which you ask the server explicitly for what you need. You can think of it as sending a string with all the keys of a JSON object, which the server should populate for you. This is what a query can look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&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="n"&gt;series&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&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;3446&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="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;suggestedEpisode&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="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;episodeNumber&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;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;Which would return:&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;"data"&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;"series"&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;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Game of Thrones"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2019&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"suggestedEpisode"&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;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Winterfell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"episodeNumber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&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;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;On C More we have completed the move to GraphQL, so all the different clients (TV clients, mobile apps and web) are using GraphQL for all their data fetching. I have been part of implementing the GraphQL server and the web implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pleasant surprises/good parts
&lt;/h2&gt;

&lt;p&gt;There are a lot of upsides to using GraphQL, and ranting about all of them would require a different format. However, there are a few things that surprised me which I want to bring up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caching and optimistic UI
&lt;/h3&gt;

&lt;p&gt;I have been using React Apollo on the client side, and I think it has just the right amount of magic to make UI development a breeze.&lt;/p&gt;

&lt;p&gt;Say you want to implement optimistic UI (assume server call will be ok, and update UI early). It is certainly possible with a lot of different technologies. But how would you update something like "Added to my list" across a) the panel showing all items in "My List", b) the item you just clicked on, and c) any other occurrence of that item? How do you roll back those changes if the request failed? It is not easy to say the least.&lt;/p&gt;

&lt;p&gt;This comes pretty much out-of-the-box with React Apollo. &lt;a href="https://www.apollographql.com/docs/react/features/optimistic-ui/"&gt;The docs&lt;/a&gt; do a great job explaining what optimistic UI is and how you implement it. The optimistic response and the actual server value will update the data in all places, thanks to the &lt;a href="https://www.apollographql.com/docs/react/advanced/caching/"&gt;cache normalization&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keeping the client code clean and stupid
&lt;/h3&gt;

&lt;p&gt;With the rise of microservices, more work is being pushed to the client side. It involves things like having multiple network round trips to fetch all data, and having to duplicate complexity between different clients. Multiple round trips are solved automatically by using GraphQL. Avoiding massaging backend data to fit the UI can be solved by introducing new GraphQL fields, which might not make sense from a backend perspective, but do make sense from a UI perspective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Works great on serverless
&lt;/h3&gt;

&lt;p&gt;As long as you do not use GraphQL subscriptions, running your GraphQL server as a serverless function works great. Since you only use a single endpoint, you will run the entire server as a single function. This gives you all of the benefits from serverless, with little to none of the downsides.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mistakes/hard parts
&lt;/h2&gt;

&lt;p&gt;GraphQL is not trivial, and implementing it won't be all good. Just as the good parts, I could write tens of blog posts about the mistakes you can make with GraphQL, but I'm just going to mention the biggest ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server side caching is tough
&lt;/h3&gt;

&lt;p&gt;C More is a SVOD service not unlike Netflix, with some personalized data (progress, recommendations, etc), and some public data (series info, episode descriptions, etc). A GraphQL query might include series details, and which episode you are on.&lt;/p&gt;

&lt;p&gt;When designing a REST API, it often is clear how "cachable" each endpoint is. The endpoint for series details will be very cachable, and which episode you are on is not.&lt;/p&gt;

&lt;p&gt;Since GraphQL is, well, a graph, you probably want to connect these two endpoints to make it possible for users to query which episode they are on for any series. This makes it harder for us to set cache policies – we would not want to recommend the wrong episode due to accidental CDN caching.&lt;/p&gt;

&lt;p&gt;There are ways around this, for example Apollo Server has &lt;a href="https://www.apollographql.com/docs/apollo-server/features/caching/"&gt;cache directives&lt;/a&gt;. In reality we found almost any query contains &lt;em&gt;some&lt;/em&gt; private data. It could be recommendations, progress, upsell data, "my list"-status, etc. Having to juggle the &lt;code&gt;cache-control&lt;/code&gt; header status for the possiblity of a few CDN cache hits just wasn't worth it for us.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not questioning backend formats
&lt;/h3&gt;

&lt;p&gt;Not all backend services are designed with the UI in mind, and when migrating from using the backend service directly to proxying it through GraphQL it is easy to just copy the data format the backend service give us.&lt;/p&gt;

&lt;p&gt;For example fetching our episodes/movies/series from our search engine, returns an array of objects with a &lt;code&gt;type&lt;/code&gt; field, which can take values such as &lt;code&gt;movie&lt;/code&gt; or &lt;code&gt;episode&lt;/code&gt;. In GraphQL, it makes more sense to actually use GraphQL types to represent that. Sadly, that was not how we implemented it the first time around. We were so used to the old format that we didn't question it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrong return type of mutations
&lt;/h3&gt;

&lt;p&gt;GraphQL mutations is how you edit data in GraphQL (&lt;code&gt;PUT&lt;/code&gt;/&lt;code&gt;POST&lt;/code&gt;/&lt;code&gt;DELETE&lt;/code&gt; in most REST APIs). What do you send as a response? A status code? A message string? Certainly possible, but that makes it impossible for something like React Apollo to update its cache automatically.&lt;/p&gt;

&lt;p&gt;By just responding with the correct data type, the clients can ask for whatever they expect to change, and all UI will magically update to their correct state. No state merging code required – it keeps the client code simple.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schema stitching
&lt;/h3&gt;

&lt;p&gt;Schema stitching is a way to split out your GraphQL implementation and schema across different servers. We tried it, and suffered.&lt;/p&gt;

&lt;p&gt;One of the largest pain points that GraphQL solved for us is gathering the microservices into a cohesive graph (it is right there in the name). Splitting the implementation across different servers increases the complexity in how you create the "edges" in your graph, and also the complexity of the entire GraphQL setup. We found that the reduced complexity of each "sub-graph" does not make up for the total increase of complexity. I feel that the fear of "monolithic" GraphQL implementations are promoting a misbegotten concept.&lt;/p&gt;

&lt;p&gt;As it stands right now, I think the GraphQL layer should be wide and flat. When you are writing a lot of "business logic" in the GraphQL layer, it probably makes more sense to create a REST-based microservice out of it.&lt;/p&gt;




&lt;p&gt;Creating a good GraphQL design is hard. It is hard to find decent sources of information and best practices – everyone is still figuring this stuff out. However I think anyone looking into implementing it should do so, it has great potential to improve your services and developer experience. Just make sure to take your time when designing the schema, getting it right the first time around will save you a lot of headache.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>react</category>
      <category>apollo</category>
    </item>
  </channel>
</rss>
