<?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: Ben Klein</title>
    <description>The latest articles on DEV Community by Ben Klein (@phortx).</description>
    <link>https://dev.to/phortx</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%2F36541%2F78e9a233-2352-427d-8b7a-df35919561d6.jpeg</url>
      <title>DEV Community: Ben Klein</title>
      <link>https://dev.to/phortx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/phortx"/>
    <language>en</language>
    <item>
      <title>Habitie.net Dev Update #2</title>
      <dc:creator>Ben Klein</dc:creator>
      <pubDate>Tue, 19 Jan 2021 15:43:13 +0000</pubDate>
      <link>https://dev.to/phortx/habitie-net-dev-update-2-anl</link>
      <guid>https://dev.to/phortx/habitie-net-dev-update-2-anl</guid>
      <description>&lt;p&gt;Welcome to the second Dev Update Post from the &lt;a href="http://habitie.net"&gt;Habitie.net&lt;/a&gt; Team 🙂&lt;/p&gt;

&lt;p&gt;Yes, I told you these posts will come every month now. And no, we couldn't keep up with that ☹️ &lt;/p&gt;

&lt;p&gt;Which leads us to the main topic of this dev update post: The struggle of keeping up the pace in a spare time project while we all have our main jobs, families, hobbies and other stuff.&lt;/p&gt;

&lt;p&gt;We have 5 people in our team currently. Each one respective with a main job, life and appointments. We have a team meeting every two weeks where we discuss current topics and plan our sprints. Our sprints last 1 month and include a planning, issues, board, review and retrospective. We're very SCRUM inspired but don't use everything from that toolbox.&lt;/p&gt;

&lt;p&gt;However the progress we have is very low currently due to the fact, that we can't work full time on the project and Habitie often loses the priority fight against other important things in our lives. Over the years we learned some lessons about how to keep up the progress and how to get something done on the project. We want to share those lessons with you here.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We keep our issues as small as possible and organize them in epics. Also we include all the important information with each issue to keep them independent and clear. That helps to quickly get into a topic and tackle it.&lt;/li&gt;
&lt;li&gt;We have a well documented and working setup guide for our repositories to enable every developer to get the project up and running without struggle or time loss.&lt;/li&gt;
&lt;li&gt;We have regular meetings and work in sprints to keep up the motivation and feedback cycles.&lt;/li&gt;
&lt;li&gt;We posts any progress we achieve in our team slack channel. It motives to see when other people on the team get something done.&lt;/li&gt;
&lt;li&gt;We encourage our team members to do small steps. You don't have to immediately finish the whole issue. Small and slow steps are good as long as they bring you in the right direction.&lt;/li&gt;
&lt;li&gt;We recommend not to "drop out" from the project. When you don't do anything for 4 weeks and then come back to work on the project you don't have any idea what's going on, where you left your code, what you're doing or who you are, then you're lost and it takes some energy and time to get back into the project after this. Thus we recommend to do something everyday even if it's just starting the server and clicking around. This will help to stay in touch with the codebase and the project.&lt;/li&gt;
&lt;li&gt;We understand that motivation is fugitive. So when you're inspired by something and you want to build somewhat amazing because you're burning for it, then do it! This will keep up the motivation and fun in the project. It's not about tackling one by one boring bug issue but it's about having fun and learning together.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We're planning to introduce further changes and ideas to improve the motivation of the team even more and to increase the progress on the project in the future. Thus we're searching vor new developers to get on the project and we think about publishing the code as OpenSource to get the community on board.&lt;/p&gt;

&lt;p&gt;Do you have any experience with spare time projects? Any suggestions or ideas? Share it with us, we're happy to hear from you 🙂&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Photo by &lt;a href="https://unsplash.com/photos/IuLgi9PWETU"&gt;Danielle MacInnes&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>Habitie.net Dev Update #1</title>
      <dc:creator>Ben Klein</dc:creator>
      <pubDate>Fri, 17 Jul 2020 09:20:47 +0000</pubDate>
      <link>https://dev.to/phortx/showdev-habitie-net-dev-update-1-4da5</link>
      <guid>https://dev.to/phortx/showdev-habitie-net-dev-update-1-4da5</guid>
      <description>&lt;p&gt;Aloha guys! 🎉&lt;/p&gt;

&lt;p&gt;I had this idea of Dev Updates for my passion project some time ago, but for some reason I had some doubts. "Is this even interesting?" or "Will they blame me?" and so on. Then I recently published my article about &lt;a href="https://dev.to/phortx/pimp-your-rails-application-32d0"&gt;UseCases as Rails Architecture&lt;/a&gt; with more or less the same doubts and the reaction of the people was awesome. Thank you so much! ❤️&lt;/p&gt;

&lt;p&gt;So I learned, that DEV.to is an exceptional kind community of nice people who are sharing stuff, giving constructive feedback and encourage each other. And I think that's amazing 😍&lt;/p&gt;

&lt;p&gt;So here we are: This is the first Dev Update post of a hopefully long chain of posts in which I want to update you folks about the development state of &lt;a href="https://www.habitie.net"&gt;habitie.net&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Idea
&lt;/h2&gt;

&lt;p&gt;First of all, what is this all about?&lt;/p&gt;

&lt;p&gt;I use lots of apps to organize my life, my work, my motivation and whatever. Wunderlist, Trello, Habitica, Evernote, Google Calendar, and much more. I really love the idea of &lt;a href="https://habitica.com/"&gt;Habitica&lt;/a&gt;. But for some reason it never really helped me in a long term. I started to collect ideas and concepts of how a app have to be so it can help me to achieve my goals, track my todos, organize my stuff and everything. At some point I had enough and started coding some stuff in my spare time. I called it habitie.&lt;/p&gt;

&lt;p&gt;The idea is to have an app with minimal gamification, where you can track your goals, define tasks, recurring tasks and habits. A habit can be negative (like smoking), positive (like doing the laundry) or both. Ticking a task or a habit gives you karma. Karma because I like the concept. You do something good (for your life or for others) and something good will come back around. Karma works like experience and you have a experience level like you know it from video games. Also you can define rewards which have a drop chance based on their rarity. Habits and Tasks have a difficulty. This together defines a drop chance for your rewards. Doing simple tasks will probably not drop the super rare epic reward (maybe a vacation or that new gaming pc you wish for), but doing the difficult habits will probably will. This way I want to bring my impulsive buying behavior under control, I think. However it motivates me we stuff I want to have is coupled with tasks I have to do. There also some builtin items, which work like buffs and give you some in-app advantage. That's the basic idea behind habitie. Besides that we have plenty of awesome concepts, ideas and features we want to add to make habitie an app which helps you to organize your life. Checklists, Boards, Notes, Integrations and so on. Stay tuned! 😁&lt;/p&gt;

&lt;h2&gt;
  
  
  The Team
&lt;/h2&gt;

&lt;p&gt;Eventually I gathered some really nice people around me to help me to build this SaaS product. Now we're a team of 5 germany and austria based dudes. Including 3 developers, a designer and a psychologist. Together we're working on this passion project in our spare time. Despite we're following a professional approach on the project. Thus we're working with the agile method, Boards, professional tool chain like InVision, GitLab, Heroku, Sentry and so on. We have regular meetings every two weeks to coordinate, talk about current topics and plan our sprints.&lt;/p&gt;

&lt;p&gt;Despite we have some really great ideas and so much on our to do list, it's difficult to keep up the pace. A passion project on which we're all working on in our spare time is struggling with the huge time effort which software development brings with it. So team growth is currently one of our highest priorities.&lt;/p&gt;

&lt;h2&gt;
  
  
  The MVP
&lt;/h2&gt;

&lt;p&gt;However we have built a MVP, which you can find on &lt;a href="https://www.habitie.net"&gt;https://www.habitie.net&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It doesn't still contain all the basic features and sure still have some bugs, but it's a good point to start from. Feel free to give it a try and share your feedback and ideas 😄 &lt;/p&gt;

&lt;p&gt;Currently we're working on a new fancy UX, the mobile app and rounding up the basic features so we can tackle the great stuff on our idea list.&lt;/p&gt;

&lt;p&gt;I want to update you on a weekly basis and hope to find some early adopters for the app.&lt;/p&gt;




&lt;p&gt;When you have questions, don't hesitate to ask. When you have feedback, please share with us. And when you want to work with us, please contact me and we'll find a way 😄&lt;/p&gt;

&lt;p&gt;Have a good time folks!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://unsplash.com/photos/ObpCE_X3j6U"&gt;Cover image by Sean Stratton&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>showdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Pimp your Rails Application</title>
      <dc:creator>Ben Klein</dc:creator>
      <pubDate>Wed, 01 Jul 2020 12:36:24 +0000</pubDate>
      <link>https://dev.to/phortx/pimp-your-rails-application-32d0</link>
      <guid>https://dev.to/phortx/pimp-your-rails-application-32d0</guid>
      <description>&lt;p&gt;Hi DEV community!&lt;/p&gt;

&lt;p&gt;Today I want to share something with you folks I've been waiting for weeks now but was to busy to write 😁&lt;/p&gt;

&lt;p&gt;It's about the question "How to structure rails applications".&lt;/p&gt;

&lt;p&gt;Finding a good and maintainable structure for large rails applications can be challenging. When you don't have a good approach, you'll end up with fat controllers and even fatter models. You keep on coding and at some point you'll lose the overview and have to maintain a spaghetti (code) monster.&lt;/p&gt;

&lt;p&gt;Rails already comes with some features to extract code from your controllers, models and views by using concerns, helpers and so on. This is nice but far not enough.&lt;/p&gt;

&lt;p&gt;Over the years I used a bunch of different approaches in a bunch of different rails apps. Starting with simple lib classes, tried Trailblazer, different gems and stuff. Finally I found a robust solution how to structure my apps to keep them clean, DRY, testable and maintainable: UseCases and Services (and Behaviors).&lt;/p&gt;

&lt;p&gt;Recently I've took alle the code which I have grown over the last 2 years and published it as a gem. Think of it as the framework and support for UseCases, Services and Behaviors. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/phortx/rails-use-case"&gt;RailsUseCase gem&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enough talked, let's dip into my take on UseCases, Services and how this gem helps you to write them without boilerplate code.&lt;/p&gt;

&lt;p&gt;For that purpose I distinguish between two types of code: low-level technical code and high-level business logic. Services are for low-level code. UseCases for business logic. Pretty simple.&lt;/p&gt;

&lt;p&gt;Now let's see what that even means ...&lt;/p&gt;

&lt;h2&gt;
  
  
  Services for Low Level Code
&lt;/h2&gt;

&lt;p&gt;Services are simple ruby classes which contain non-domain logic for low level, technical stuff. For example downloading a file from a FTP server, communication with an API, CSV generation, attaching a webcam image to a record, whatever. &lt;/p&gt;

&lt;p&gt;Services are placed in the &lt;code&gt;app/services&lt;/code&gt; directory and should be named like &lt;code&gt;csv_generation_service.rb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A example service could look like 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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PDFGenerationService&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Service&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:pdf_template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:values&lt;/span&gt;

  &lt;span class="c1"&gt;# Constructor.&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="s1"&gt;'pdf_generation'&lt;/span&gt;
    &lt;span class="n"&gt;prepare&lt;/span&gt;
    &lt;span class="n"&gt;validate_libreoffice&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;


  &lt;span class="c1"&gt;# Entry point.&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# @param [PdfTemplate] pdf_template PdfTemplate record.&lt;/span&gt;
  &lt;span class="c1"&gt;# @param [Hash&amp;lt;String, String&amp;gt;] values Mapping of variables to their values.&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# @returns [String] Path to PDF file.&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdf_template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="vi"&gt;@pdf_template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pdf_template&lt;/span&gt;
    &lt;span class="vi"&gt;@values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prepare_variable_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;write_odt_file&lt;/span&gt;
    &lt;span class="n"&gt;replace_variables&lt;/span&gt;
    &lt;span class="n"&gt;generate_pdf&lt;/span&gt;

    &lt;span class="vi"&gt;@pdf_file_path&lt;/span&gt;
  &lt;span class="k"&gt;ensure&lt;/span&gt;
    &lt;span class="n"&gt;delete_tempfile&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 &lt;code&gt;Rails::Service&lt;/code&gt; class comes with some handy features to make your life easier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call style invocation: &lt;code&gt;PDFGenerationService.(some, params)&lt;/code&gt; which is the same as &lt;code&gt;PDFGenerationService.call(some, params)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;They are configurable and automatically load their configuration both from &lt;code&gt;config/services/shared.yml&lt;/code&gt; and &lt;code&gt;config/services/[service_name].yml&lt;/code&gt;. You can access the config as a hash via calling &lt;code&gt;config&lt;/code&gt; within the service.&lt;/li&gt;
&lt;li&gt;Each service writes it's own log file to &lt;code&gt;log/services/[service_name].log&lt;/code&gt;. You can access the logger via &lt;code&gt;logger&lt;/code&gt; within the service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Services replace what was usually done via lib files. They have a clear structure, are reusable, DRY and are easy to test.&lt;/p&gt;

&lt;h2&gt;
  
  
  UseCases for Business Logic
&lt;/h2&gt;

&lt;p&gt;While the service contains low-level non-business logic, UseCases are for the opposite: high-level business logic and they replace fat controllers. A UseCase takes params and has a outcome, which is successfully or failed. Examples are: Place an item in the cart, create a new user or delete a comment.&lt;/p&gt;

&lt;p&gt;Use Cases should be placed in the &lt;code&gt;app/use_cases&lt;/code&gt; directory and the file and class name should start with a verb like &lt;code&gt;create_blog_post.rb&lt;/code&gt;. I also highly recommend to namespace all use cases with the model module like &lt;code&gt;blog_posts/create.rb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example UseCase for creating a blog post:&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="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;BlogPosts&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Create&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;UseCase&lt;/span&gt;
    &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:skip_notifications&lt;/span&gt;

    &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;

    &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ss"&gt;:build_post&lt;/span&gt;
    &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ss"&gt;:save!&lt;/span&gt;
    &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ss"&gt;:notify_subscribers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;unless: &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;skip_notifications&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_post&lt;/span&gt;
      &lt;span class="vi"&gt;@record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;BlogPost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;created_by: &lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;type: :default&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;notify_subscribers&lt;/span&gt;
      &lt;span class="c1"&gt;# ... send some mails ...&lt;/span&gt;
    &lt;span class="k"&gt;end&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;Let's take a look on the details: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can define the params of the UseCase by defining &lt;code&gt;attr_accessors&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The params should always passed as hash and are automatically assigned to instance variables.&lt;/li&gt;
&lt;li&gt;We can define validations for those params via ActiveRecord Validations. These are automatically executed when calling the UseCase&lt;/li&gt;
&lt;li&gt;The logic of the UseCase is defined by &lt;code&gt;step&lt;/code&gt;s. Each step calls the method with the same name. They can be skipped via &lt;code&gt;if&lt;/code&gt; or &lt;code&gt;unless&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Steps are executed in the defined order. Only when a step succeeds (returns &lt;code&gt;true&lt;/code&gt;) the next step will be executed. Steps can be skipped via &lt;code&gt;if&lt;/code&gt; or &lt;code&gt;unless&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The UseCase should assign the main record which is handled within the Case to &lt;code&gt;@record&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Calling &lt;code&gt;save!&lt;/code&gt; without argument will try to save that record or raises an exception. Also the &lt;code&gt;@record&lt;/code&gt; will automatically passed into the outcome.&lt;/li&gt;
&lt;li&gt;raising a &lt;code&gt;UseCase::Error&lt;/code&gt; immediately stops the UseCase and saves the exception in the outcome.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Calling a UseCase looks like 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;outcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;BlogPost&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s1"&gt;'Super Awesome Stuff!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s1"&gt;'Lorem Ipsum Dolor Sit Amet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;created_by: &lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;skip_notifications: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; {&lt;/span&gt;
&lt;span class="c1"&gt;#   success: true,&lt;/span&gt;
&lt;span class="c1"&gt;#   record: BlogPost(...)&lt;/span&gt;
&lt;span class="c1"&gt;#   errors: [],&lt;/span&gt;
&lt;span class="c1"&gt;#   exception: nil&lt;/span&gt;
&lt;span class="c1"&gt;# }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;outcome.success?&lt;/code&gt; Tells whether the UseCase was successful.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;outcome.record&lt;/code&gt; Contains the record which was assigned to &lt;code&gt;@record&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;outcome.errors&lt;/code&gt; Contain validation messages when the validation failed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;outcome.exception&lt;/code&gt; Contains the &lt;code&gt;UseCase::Error&lt;/code&gt; exception when any was raised.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;UseCases may call other UseCases and use Services.&lt;/p&gt;

&lt;p&gt;Each controller action or GraphQL mutation should do nothing than calling a UseCase and handle the outcome. This way you have packed your business logic in highly reusable, robust, elegant and clean ruby classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Behaviors
&lt;/h2&gt;

&lt;p&gt;When working with UseCases you will probably have duplicated code at some point. Behaviors allow you to share code between UseCases.&lt;/p&gt;

&lt;p&gt;Behaviors should be placed in the &lt;code&gt;app/behaviors&lt;/code&gt; directory and the file and module name should named in a way it can be prefixed with &lt;code&gt;with&lt;/code&gt; and should end with &lt;code&gt;behavior&lt;/code&gt;, like &lt;code&gt;current_user_behavior.rb&lt;/code&gt; (read: &lt;code&gt;with current user&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;To use a Behavior in a UseCase, use the &lt;code&gt;with&lt;/code&gt; directive, like &lt;code&gt;with CurrentUserBehavior&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example Behavior for accessing the current user of &lt;a href="https://github.com/binarylogic/authlogic"&gt;AuthLogic&lt;/a&gt;:&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="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;CurrentUserBehavior&lt;/span&gt;
  &lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;session&lt;/span&gt;
    &lt;span class="no"&gt;UserSession&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;current_user&lt;/span&gt;
    &lt;span class="no"&gt;UserSession&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;record&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;Example usage:&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="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;BlogPosts&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Create&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;UseCase&lt;/span&gt;
    &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="no"&gt;CurrentUserBehavior&lt;/span&gt;

     &lt;span class="c1"&gt;# ...&lt;/span&gt;

    &lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_post&lt;/span&gt;
      &lt;span class="vi"&gt;@record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;BlogPost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;created_by: &lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;type: :default&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# ...&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 way you have an elegant way to share logic between your UseCases to keep them as small as possible.&lt;/p&gt;

&lt;p&gt;I hope I could explain the advantages of using these classes to structure a rails application and would be happy when this helps you to improve your app. Please give feedback for the gem and don't forget to star the project 😉&lt;/p&gt;

&lt;p&gt;Thanks for the read. Have a nice day and keep coding! ❤️ 👨‍💻&lt;/p&gt;

&lt;p&gt;Header image made by &lt;a href="https://unsplash.com/photos/MSN8TFhJ0is"&gt;Safar Safarov @ Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>architecture</category>
    </item>
    <item>
      <title>I started a list of ruby gems and their crystal shard replacement</title>
      <dc:creator>Ben Klein</dc:creator>
      <pubDate>Mon, 24 Jun 2019 19:21:11 +0000</pubDate>
      <link>https://dev.to/phortx/i-started-a-list-of-ruby-gems-and-their-crystal-shard-replacement-l25</link>
      <guid>https://dev.to/phortx/i-started-a-list-of-ruby-gems-and-their-crystal-shard-replacement-l25</guid>
      <description>&lt;p&gt;I basically just created the repo. Help me to fill the list! :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/phortx/ruby-gem-to-crystal-list/"&gt;https://github.com/phortx/ruby-gem-to-crystal-list/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>crystal</category>
      <category>rails</category>
      <category>ruby</category>
    </item>
    <item>
      <title>What's new in Vuex-ORM/Plugin-GraphQL</title>
      <dc:creator>Ben Klein</dc:creator>
      <pubDate>Thu, 18 Oct 2018 12:32:41 +0000</pubDate>
      <link>https://dev.to/phortx/whats-new-in-vuex-ormplugin-graphql-4fd9</link>
      <guid>https://dev.to/phortx/whats-new-in-vuex-ormplugin-graphql-4fd9</guid>
      <description>&lt;p&gt;(Photo by &lt;a href="https://unsplash.com/photos/hFtucUnQFa4" rel="noopener noreferrer"&gt;rawpixel&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://vuex-orm.github.io/plugin-graphql/" rel="noopener noreferrer"&gt;Vuex-ORM GraphQL Plugin&lt;/a&gt; and this article are powered by &lt;a href="https://i22.de" rel="noopener noreferrer"&gt;i22 Digitalagentur&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since my &lt;a href="https://dev.to/phortx/vue-3-graphql-kj6"&gt;first post about the Vuex-ORM GraphQL Plugin in may&lt;/a&gt; some time has passed and while that, a lot of changes have been introduced. In this article I want to show you what cool new features we got, what has changed and where we're going.&lt;/p&gt;

&lt;h2&gt;
  
  
  Renaming of the plugin
&lt;/h2&gt;

&lt;p&gt;First of all we renamed the plugin to have a consistent naming across all the Vuex-ORM the plugins. The Plugin is now called Vuex-ORM/Plugin-GraphQL and thus the NPM package is named &lt;code&gt;@vuex-orm/plugin-graphql&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Moving ahead 1.0.0
&lt;/h2&gt;

&lt;p&gt;To make clear, that we are approaching a stable API, I'm currently releasing Release Candidates for 1.0.0. While writing this article we already have RC 21.&lt;/p&gt;

&lt;p&gt;In parallel the Maintainers of Vuex-ORM and the plugins are talking about a consistent API across all persistence plugins. When this API specification is finished, we're ready for 1.0.0. Please keep in mind that until finishing the spec, the API of the Plugin will probably change. I'll keep you up to date.&lt;/p&gt;

&lt;h2&gt;
  
  
  Convenience methods
&lt;/h2&gt;

&lt;p&gt;We got clean a API with convenience methods now. No more calling &lt;code&gt;dispatch()&lt;/code&gt;, instead you can use &lt;code&gt;fetch()&lt;/code&gt;, &lt;code&gt;$persist()&lt;/code&gt;, &lt;code&gt;$deleteAndDestroy()&lt;/code&gt; and many more!&lt;/p&gt;

&lt;h2&gt;
  
  
  Support for response mocking in unit tests
&lt;/h2&gt;

&lt;p&gt;One of the latest RC versions brought response mocking support for Vue Unit Tests of components, that interact with the GraphQL server.&lt;/p&gt;

&lt;p&gt;Please check the &lt;a href="https://vuex-orm.github.io/plugin-graphql/guide/testing/" rel="noopener noreferrer"&gt;testing section in the documentation&lt;/a&gt; for details.&lt;/p&gt;

&lt;h2&gt;
  
  
  GrpahQL schema analyzing
&lt;/h2&gt;

&lt;p&gt;When the first query or mutation to the GraphQL API is sent, the plugin sends a introspection query to the API, downloads the schema, analyzes it and extracts different information like the types of the fields to use, which fields to ignore, because they're not in the schema and whether custom queries and mutations return a connection or a record.&lt;/p&gt;

&lt;p&gt;Further it detects differences between the Vuex-ORM model definitions and the schema and logs warnings.&lt;/p&gt;

&lt;p&gt;In the future there will probably be more smart consulting of your GraphQL schema, we're open for suggestions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support for different API designs
&lt;/h2&gt;

&lt;p&gt;Due to the fact that there is no fixed way to design a GraphQL API and there are at least 3 ways how connections could look like, the plugin now brings support for all of them, via a &lt;code&gt;connectionMode&lt;/code&gt; setting. This will be automatically determined by analyzing the schema, so you don't have to configure anything. However, if that fails, you can explicitly overwrite the connection mode via config.&lt;/p&gt;

&lt;p&gt;Checkout the &lt;a href="https://vuex-orm.github.io/plugin-graphql/guide/connection-mode/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; to see what connection types are supported.&lt;/p&gt;

&lt;p&gt;In the future the plugin will get even more flexible and allows the developer to change the naming of the C(R)UD mutations. Stay tuned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support for custom queries and mutations
&lt;/h2&gt;

&lt;p&gt;Because not all mutations are Create/Update/Delete and because not all queries can be generated automatically, the plugin now also supports custom queries and mutations. Either related to a model or not.&lt;/p&gt;

&lt;p&gt;Take a look a &lt;a href="https://vuex-orm.github.io/plugin-graphql/guide/custom-queries/" rel="noopener noreferrer"&gt;the documentation&lt;/a&gt; to get an idea how to use custom queries and mutations&lt;/p&gt;

&lt;h2&gt;
  
  
  Support for HTTP headers
&lt;/h2&gt;

&lt;p&gt;Setting HTTP headers either static when initializing the plugin or dynamic by passing a function is the key to setup Authentication mechanisms and a often requested feature. The plugin supports this now!&lt;/p&gt;

&lt;h2&gt;
  
  
  Lots of bugfixes and documentation improvements
&lt;/h2&gt;

&lt;p&gt;Along with those changes came a big bunch of bugfixes, improvements both for the code and the documentation.&lt;/p&gt;

&lt;p&gt;I also reduced the number of dependencies of the plugin to &lt;strong&gt;1&lt;/strong&gt; (!). Which is a very slim signature for a NPM package :)&lt;/p&gt;

&lt;h2&gt;
  
  
  SSR Support
&lt;/h2&gt;

&lt;p&gt;Support for server side rendering and Nuxt.js is experimental since RC 21. Please give feedback if it works for you!&lt;/p&gt;




&lt;p&gt;As you can see, we got same pace in the project and we're approaching version 1.0.0 very quickly. You're invited to join our support slack channel or open a GitHub issue. We love to hear your feedback!&lt;/p&gt;

&lt;p&gt;This OpenSource project is build with ❤️ at &lt;a href="https://i22.de" rel="noopener noreferrer"&gt;i22&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>vuex</category>
      <category>graphql</category>
    </item>
    <item>
      <title>Need your help: Show me your GraphQL Schema</title>
      <dc:creator>Ben Klein</dc:creator>
      <pubDate>Tue, 03 Jul 2018 12:40:50 +0000</pubDate>
      <link>https://dev.to/phortx/need-your-help-show-me-your-graphql-schema-15d1</link>
      <guid>https://dev.to/phortx/need-your-help-show-me-your-graphql-schema-15d1</guid>
      <description>&lt;p&gt;Hello Community!&lt;/p&gt;

&lt;p&gt;I need your help. I'm the maintainer of &lt;a href="https://dev.to/phortx/vue-3-graphql-kj6"&gt;Vuex-ORM-GraphQL&lt;/a&gt;. It's a tough job to cover all those different ways to design a GraphQL Schema. You would help me a lot if you could run  the introspection query below against your GraphQL API and send me the result.&lt;/p&gt;

&lt;p&gt;This way I can analyze what different schema designs are out there and write unit tests to ensure that my plugin can handle them all :)&lt;/p&gt;

&lt;p&gt;Disclaimer: Please make sure it's ok to send me the schema! Don't send me any secret or sensible information you may be sentenced for. However I promise to keep the stuff you send me secret and I will delete it right after analyzing it. I will not use them for any other purpose or distribute it.&lt;/p&gt;

&lt;p&gt;Here is the introspection schema, you can run it against your API by using GraphiQL for example.&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;__schema&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;types&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;name&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="w"&gt;

      &lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;includeDeprecated&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;args&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;name&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;type&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;name&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="w"&gt;

            &lt;/span&gt;&lt;span class="n"&gt;ofType&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;kind&lt;/span&gt;&lt;span class="w"&gt;

              &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="n"&gt;ofType&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;kind&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;

                &lt;/span&gt;&lt;span class="n"&gt;ofType&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;kind&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="n"&gt;name&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;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="n"&gt;type&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;name&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="w"&gt;

          &lt;/span&gt;&lt;span class="n"&gt;ofType&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;kind&lt;/span&gt;&lt;span class="w"&gt;

            &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="n"&gt;ofType&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;kind&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;

              &lt;/span&gt;&lt;span class="n"&gt;ofType&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;kind&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;name&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;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

      &lt;/span&gt;&lt;span class="n"&gt;inputFields&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;name&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="n"&gt;type&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;name&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="w"&gt;

          &lt;/span&gt;&lt;span class="n"&gt;ofType&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;kind&lt;/span&gt;&lt;span class="w"&gt;

            &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="n"&gt;ofType&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;kind&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;

              &lt;/span&gt;&lt;span class="n"&gt;ofType&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;kind&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;name&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;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;Send me the result as a private gist to &lt;a href="mailto:bk@itws.de"&gt;bk@itws.de&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you very much for your help!&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>vue</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Vue &lt;3 GraphQL</title>
      <dc:creator>Ben Klein</dc:creator>
      <pubDate>Mon, 28 May 2018 08:34:33 +0000</pubDate>
      <link>https://dev.to/phortx/vue-3-graphql-kj6</link>
      <guid>https://dev.to/phortx/vue-3-graphql-kj6</guid>
      <description>&lt;p&gt;TL;DR: I made dis: &lt;a href="https://vuex-orm.github.io/vuex-orm-graphql/" rel="noopener noreferrer"&gt;https://vuex-orm.github.io/vuex-orm-graphql/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is my first article on dev.to and I want to use this to share my current open source project with this amazing community :)&lt;/p&gt;

&lt;p&gt;The GraphQL Plugin for Vuex-ORM and this article is powered by the Germany based &lt;a href="https://i22.de" rel="noopener noreferrer"&gt;i22 Digitalagentur GmbH&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The beginning of journey
&lt;/h2&gt;

&lt;p&gt;In my current side project, I was using a JSON/REST API and attached the Frontend Single Page Application via JSData. A setup that never made me really happy and brought a lot of issues. &lt;/p&gt;

&lt;p&gt;Then I discovered &lt;a href="https://vuex-orm.github.io/vuex-orm/" rel="noopener noreferrer"&gt;Vuex-ORM&lt;/a&gt; which brings everything I need to work with models in Vue and also has real reactivity, is blazing fast and uses Vuex. I felt like I replace JSData with Vuex-ORM. But: There have been no plugins to attach an API. I don't want to have too much boilerplate in my components and I don't like to fiddle around with the specifics of the communication with the API. Integrating your Single Page Application with your API can be a pain. But it shouldn't.&lt;/p&gt;

&lt;p&gt;At same time earlier this year, I've learned about GraphQL in my new full time job. And it was amazing. After some playing around, I've stated to love it and felt like I could replace the REST/JSON API of my side project with GraphQL.&lt;/p&gt;

&lt;p&gt;Then we were starting a project in my full-time job at &lt;a href="The%20GraphQL%20Plugin%20for%20Vuex-ORM%20and%20this%20article%20is%20powered%20by%20the%20Germany%20based%20[i22%20Digitalagentur%20GmbH](https://i22.de)."&gt;i22&lt;/a&gt; with a very similar setup like my side project, so I decided to give Vuex-ORM a try. But we have committed to use GraphQL (like in all our other projects). Like there was no JSON/REST plugin for Vuex-ORM there was also no GraphQL plugin. I thought, I could write one. Shouldn't be that difficult, I thought: We already have our model definitions and a GraphQL API, I just could transform the model definitions into a GraphQL query. I could use the apollo-client lib. This plugin should make the communication with the API a pleasure. No boilerplate, no fiddling together JSON structures or whatever. So let's start!&lt;/p&gt;

&lt;p&gt;It was a lot more difficult then I thought, but after some weeks of development, I had a basically working plugin which has a minimal component boilerplate and just works with reactivity and all that fancy stuff.&lt;/p&gt;

&lt;p&gt;Time to go the next step: Migrate my side project from JSON/REST + JSData to Vuex-ORM + GraphQL. While doing that I discovered some bugs in my plugin and fixed them, wrote some more tests and added some missing features.&lt;/p&gt;

&lt;p&gt;Today, some months of finetuning, testing and a lot of help from &lt;a href="https://github.com/kiaking" rel="noopener noreferrer"&gt;Kia&lt;/a&gt;, the very kind and smart maintainer of Vuex-ORM, later, I have a well working GraphQL Plugin for Vuex-ORM with all basic features, documentation and two of my current projects using it. It works like a charm. I'm very happy with it currently :)&lt;/p&gt;

&lt;p&gt;Now it's time to share my work with the community. In the rest of this article I will show you how the Vuex-ORM-GraphQL plugin works and how you can use it in your project. Please remember: This is just a basic example. For more details, please take a look in the documentations both of &lt;a href="https://vuex-orm.github.io/vuex-orm/" rel="noopener noreferrer"&gt;Vuex-ORM&lt;/a&gt; and &lt;a href="https://vuex-orm.github.io/vuex-orm-graphql" rel="noopener noreferrer"&gt;Vuex-ORM-GraphQL&lt;/a&gt;. Have fun!&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;I assume you have experience with Vue and maybe GraphQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vuex-ORM
&lt;/h3&gt;

&lt;p&gt;First of all we have to setup Vuex-ORM, which is pretty simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add @vuex-orm/core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create a &lt;code&gt;store.js&lt;/code&gt; and a &lt;code&gt;models&lt;/code&gt; directory somewhere in your app.&lt;/p&gt;

&lt;p&gt;Let's assume we're building a simple blog. There are &lt;code&gt;posts&lt;/code&gt; and &lt;code&gt;comments&lt;/code&gt;. So we need two models. Let's create them in our new &lt;code&gt;models&lt;/code&gt; directory:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;models/post.js&lt;/code&gt;:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vuex-orm/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Comment&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./comment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * The Vuex-ORM post model
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Tell Vuex-ORM the path where the records should be stored in Vuex&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;entity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Tell Vuex-ORM-GraphQL to eagerly load all comments when we fetch a post.&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;eagerLoad&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="s1"&gt;comments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="c1"&gt;// Setup the fields and relations for Vuex-ORM&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;fields &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="na"&gt;publishedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

            &lt;span class="na"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Comment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postId&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;models/comment.js&lt;/code&gt;:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vuex-orm/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * The Vuex-ORM comment model
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Comment&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Tell Vuex-ORM the path where the records should be stored in Vuex&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;entity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Setup the fields for Vuex-ORM&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;fields &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="na"&gt;publishedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

            &lt;span class="na"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;belongsTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postId&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, setting up a model for Vuex-ORM is very easy. Now we have to setup our Vuex store like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;store.js&lt;/code&gt;&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vuex&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vuex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;VuexORM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vuex-orm/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./models/post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Comment&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./models/comment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="c1"&gt;// Setup Vuex&lt;/span&gt;
&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Vuex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Setup Vuex-ORM database&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;VuexORM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Comment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;

&lt;span class="c1"&gt;// Create Vuex Store and register the Vuex ORM plugin.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vuex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;VuexORM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;install&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;database&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;After that we can already create new records, find them, change them and delete them in a component:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;store/models/post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Example Blog Post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lorem ipsum dolor sit amet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;publishedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Vuex-ORM GraphQL Plugin
&lt;/h3&gt;

&lt;p&gt;In the next step we setup my new GraphQL Plugin for Vuex-ORM, which is amazing simple, because the plugin hides all the complexity of the apollo-http-link, apollo-client and so on from you. It's designed to be installed and just work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add @vuex-orm/plugin-graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the &lt;code&gt;store.js&lt;/code&gt; 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="c1"&gt;// ...&lt;/span&gt;
&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Comment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;

&lt;span class="c1"&gt;// --8&amp;lt;-------------&lt;/span&gt;
&lt;span class="c1"&gt;// This is the new part&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;installVuexORMGraphQL&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vuex-orm/plugin-graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;VuexORM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;installVuexORMGraphQL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// --8&amp;lt;-------------&lt;/span&gt;

&lt;span class="c1"&gt;// Create Vuex Store and register the Vuex ORM plugin.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vuex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;VuexORM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;install&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;database&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;Not much magic here, we just register the Vuex-ORM-GraphQL plugin as a Vuex-ORM plugin and pass the database. Nothing more to do. As I said: Setup I super easy ;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Store vs Persistence Actions
&lt;/h3&gt;

&lt;p&gt;While using Vuex-ORM with the GraphQL plugin you have to distinct between two types of Vuex actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store actions: Retrieve data from or save data to the Vuex Store (&lt;code&gt;Vue Component &amp;lt;--&amp;gt; Vuex Store&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Persistence actions: Load data from or persist data to the GraphQL API (&lt;code&gt;Vuex Store &amp;lt;--&amp;gt; GraphQL Server&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following table lists all actions and what they do:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CRUD&lt;/th&gt;
&lt;th&gt;Vuex Only&lt;/th&gt;
&lt;th&gt;Persist to GraphQL API&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;R&lt;/strong&gt;EAD&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://vuex-orm.github.io/vuex-orm/store/retrieving-data.html#get-single-data" rel="noopener noreferrer"&gt;&lt;code&gt;find()&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://vuex-orm.github.io/vuex-orm/store/retrieving-data.html#get-all-data" rel="noopener noreferrer"&gt;&lt;code&gt;all()&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://vuex-orm.github.io/vuex-orm/store/retrieving-data.html#query-builder" rel="noopener noreferrer"&gt;&lt;code&gt;query()&lt;/code&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;&lt;a href="https://vuex-orm.github.io/vuex-orm-graphql/guide/fetch" rel="noopener noreferrer"&gt;&lt;code&gt;fetch()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;C&lt;/strong&gt;REATE&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://vuex-orm.github.io/vuex-orm/store/inserting-and-updating-data.html#inserts" rel="noopener noreferrer"&gt;&lt;code&gt;create()&lt;/code&gt;&lt;/a&gt; or &lt;a href="https://vuex-orm.github.io/vuex-orm/store/inserting-and-updating-data.html#inserts" rel="noopener noreferrer"&gt;&lt;code&gt;insert()&lt;/code&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;&lt;a href="https://vuex-orm.github.io/vuex-orm-graphql/guide/persist" rel="noopener noreferrer"&gt;&lt;code&gt;$persist()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;U&lt;/strong&gt;PDATE&lt;/td&gt;
&lt;td&gt;&lt;a href="https://vuex-orm.github.io/vuex-orm/store/inserting-and-updating-data.html#updates" rel="noopener noreferrer"&gt;&lt;code&gt;$update()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://vuex-orm.github.io/vuex-orm-graphql/guide/push" rel="noopener noreferrer"&gt;&lt;code&gt;$push()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;D&lt;/strong&gt;ELETE&lt;/td&gt;
&lt;td&gt;&lt;a href="https://vuex-orm.github.io/vuex-orm/store/deleting-data.html" rel="noopener noreferrer"&gt;&lt;code&gt;$delete()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://vuex-orm.github.io/vuex-orm-graphql/guide/destroy" rel="noopener noreferrer"&gt;&lt;code&gt;$destroy()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;After our setup we can use Vuex-ORM to fetch data from the GraphQL API and display it reactively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blog"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"post in posts"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"post.id"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blog__post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;small&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publishedAt&lt;/span&gt;&lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/small&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click.prevent=&lt;/span&gt;&lt;span class="s"&gt;"destroy(post)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Delete this post&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;hr&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"comments"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Comments&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"comment in posts.comments"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"comment.id"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"comments__comment"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;From &lt;span class="si"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data/models/post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Returns all posts with reactivity.&lt;/span&gt;
      &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;mounted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Load all posts form the GraphQL API.&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Deletes the post from Vuex Store and from the server.&lt;/span&gt;
      &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$deleteAndDestroy&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;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's all the required code to load the blog posts and comments from the server, display them and allow the user to delete the post.&lt;/p&gt;

&lt;h3&gt;
  
  
  GraphQL Queries
&lt;/h3&gt;

&lt;p&gt;The code above generates following GraphQL query for &lt;code&gt;fetch&lt;/code&gt;:&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="n"&gt;Posts&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;posts&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;nodes&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;id&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;content&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;publishedAt&lt;/span&gt;&lt;span class="w"&gt;

      &lt;/span&gt;&lt;span class="n"&gt;comments&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;nodes&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;id&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;publishedAt&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;postId&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;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;And the following GraphQL mutation for &lt;code&gt;destroy&lt;/code&gt;:&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;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DeletePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&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;deletePost&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="nv"&gt;$id&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;id&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;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There's still a lot of work to do: The code is a mess at some points, there are some missing tests, subscriptions are not implemented yet, there could be much more configurability and the documentation is not finished yet. But I thought it's time to share my work with the community to get feedback and hopefully get some contributions to bring the plugin to a stable version 1.0.0.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;PS: The side project launches soon. I will make a post about it when the time case come ;)&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>vue</category>
      <category>vuex</category>
    </item>
  </channel>
</rss>
