{"id":14976151,"url":"https://github.com/yvsssantosh/posts_graphql","last_synced_at":"2026-02-24T05:40:05.821Z","repository":{"id":40135907,"uuid":"259284489","full_name":"yvsssantosh/posts_graphql","owner":"yvsssantosh","description":"A demo project explaining installation and working of a Rails Backend using GraphQL","archived":false,"fork":false,"pushed_at":"2023-01-19T18:36:55.000Z","size":1346,"stargazers_count":1,"open_issues_count":8,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-23T21:41:51.243Z","etag":null,"topics":["database","graphql","graphql-query","postgresql","rails-backend","rails-server","ruby"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yvsssantosh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-27T10:46:09.000Z","updated_at":"2021-06-01T09:40:51.000Z","dependencies_parsed_at":"2023-02-11T15:55:22.835Z","dependency_job_id":null,"html_url":"https://github.com/yvsssantosh/posts_graphql","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/yvsssantosh/posts_graphql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yvsssantosh%2Fposts_graphql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yvsssantosh%2Fposts_graphql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yvsssantosh%2Fposts_graphql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yvsssantosh%2Fposts_graphql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yvsssantosh","download_url":"https://codeload.github.com/yvsssantosh/posts_graphql/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yvsssantosh%2Fposts_graphql/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29773327,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-24T04:54:30.205Z","status":"ssl_error","status_checked_at":"2026-02-24T04:53:58.628Z","response_time":75,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","graphql","graphql-query","postgresql","rails-backend","rails-server","ruby"],"created_at":"2024-09-24T13:53:23.749Z","updated_at":"2026-02-24T05:40:05.760Z","avatar_url":"https://github.com/yvsssantosh.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Running a Rails server with GraphQL and GraphiQL\nThis tutorial gives a brief to understand how to build a Rails backend server with GraphQL integration. Since there's no frontend involved, we'll be using GraphiQL to make the requests to our server.\n\n### Why Ruby?\nRuby is a very high level language, which means Ruby abstracts away (i.e. handles for you) most of the complex details of the machine. Thus, you can quickly build something from scratch with less lines of code. Ruby was made popular by the Ruby on Rails framework, a full-stack web framework that makes prototyping a breeze, making it a web framework of choice for many startups and coding beginners alike.\n\nReasons why one should learn ruby:\n1. Beginner Friendliness\n2. Has a wide community for support\n4. One more backend development tool to the resume! and many more!!\n\n## Setup\nThe aim of this project is to build a basic Posts API where we have a user adding particular posts, using Rails and GraphQL.\n\n```sh\n# Installing ruby\n# To keep control of which version of Ruby we're using, I'd recommend using rvm\n# RVM setup has been documented here --\u003e https://rvm.io/rvm/install\nrvm install 2.6.5\n\n# Installing rails globally\n# Just like we do in node, we need to install rails globally once\ngem install rails\n```\n\nNow that we have rails installed and setup, lets setup our project\n\n## Getting Started with Rails\n\n```sh\n# Generate code for a sample project\nrails new posts_graphql -d postgresql --api --skip-tests --skip-action-mailbox --skip-action-text --skip-spring -T --skip-turbolinks --skip-active-storage\n\n# Explaining the parameters passed\n#   -d              ---\u003e        Specify the database being used, in our case postgresql.\n#                               Options include sqlite3, mysql, etc\n#   --api           ---\u003e        For API only apps, we don't need to load frontend modules.\n#   --sktip-NAME    ---\u003e        This option is used to skip a particular module\n#                               which come by default when generating a rails application\n# Here we are skipping the modules --\u003e tests, action-inbox, action-text, turbolinks and active-storage,\n# as we won't be using them in the project\n# \n```\n![](./images/directory_structure.png)\n\nNavigate to `config/database.yml` and fill the appropriate values pertaining to username, password etc. as they're used to connect to the database\n\n```yml\n# Example\ndevelopment:\n  \u003c\u003c: *default\n  database: rails_posts_db\n\n  # The specified database role being used to connect to postgres.\n  # To create additional roles in postgres see `$ createuser --help`.\n  # When left blank, postgres will use the default role. This is\n  # the same name as the operating system user that initialized the database.\n  username: rails_posts_user\n\n  # The password associated with the postgres role (username).\n  password: rails_posts_password\n\n  # Connect on a TCP socket. Omitted by default since the client uses a\n  # domain socket that doesn't need configuration. Windows does not have\n  # domain sockets, so uncomment these lines.\n  host: localhost\n\n  # The TCP port the server listens on. Defaults to 5432.\n  # If your server runs on a different port number, change accordingly.\n  port: 5432\n```\n\nNow that we're connected to the database and generated a sample project lets generate models for the same. The key thing is, even though we'll be using GraphQL, we'll still use the models generated by rails.\n\n```sh\n# Generating models\n# Generating User model with fields \n#    `name`       : datatype -\u003e string\n#    `email`      : datatype -\u003e string\nrails generate model User name:string email:string\n\n# Generating Post model with fields \n#    `user`       : datatype -\u003e User\n#    `title`       : datatype -\u003e string\n#    `body`       : datatype -\u003e text\nrails generate model Post user:belongs_to title:string body:text\n\n```\n\nNow that we have the models setup, lets run the migrations. To run migrations, run the command `rails db:migrate`\n\n![](./images/migration.png)\n\nNow lets naviagate to `app/models`. Inside this folder, we should be seeing four newly created files, `user.rb` and `post.rb`.\n\nFor a Posting System, we know that, \n```sh\n# Post      -\u003e  belongs to      -\u003e User\n\n# We need to define the relationships\n# User      -\u003e  can have many   -\u003e Posts\n```\n\nSo lets go to `user.rb` to update the code accordingly (as the second part i.e. `User -\u003e can have many -\u003e posts` was not auto generated)\n\n```rb\n# user.rb\nclass User \u003c ApplicationRecord\n    has_many :posts\nend\n```\n\nNow that we're all set, lets install GraphQL and GraphiQL. We can do this simply by adding their respective gems to the `Gemfile`. We're also going to install `Faker` gem to pre-populate/seed the database with sample values\n\n```\ngem 'graphql'\n\ngroup :development do\n  # Any existing code\n  gem 'graphiql-rails'\n  gem 'faker'\nend\n```\n\nOnce the `Gemfile` is modified, just run the command `bundle install` in the root directory of the project to install any missing gems. Now that we're done with installation, lets seed some data. Update the `seeds.rb` as below\n\n```rb\n# seeds.rb\n# We're using Faker to generate random emails, for testing purposes\n5.times do\n    user = User.create(name: Faker::Name.name, email: Faker::Internet.email)\n    5.times do\n        user.posts.create(title: Faker::Lorem.sentence(word_count: 2), body: Faker::Lorem.paragraph(sentence_count: 3))\n    end\nend\n```\nLets then run the command `rails db:seed`. If nothing is shown as output, it means the command has executed successfully. Now that we have the data, lets start using graphql\n\n## Generating GraphQL Code\n\nRemember we had installed the gems for GraphQL and GraphiQL. Lets setup the GraphQL installation now.\n\n```sh\n# Setting up GraphQL code in our project\n# Note: Only works if GraphQL gem is pre-installed \n# (we did it earlier when running `bundle install`)\nrails generate graphql:install\n```\nNote that this command is very handy and auto-generates a lot of code for us. After running this command, we can see a new folder `graphql` has been created in the `app` directory. Also, `config/routes.rb` has also been automatically updated with the default graphql endpoint, which we'll be using to mutate and list the data in our database.\n\nWith that installed, we have to configure our Rails models as GraphQL Objects. This can be done as another generation.\n```sh\nrails generate\n# ...\n# Graphql:\n#   graphql:enum\n#   graphql:install\n#   graphql:interface\n#   graphql:loader              \n#   graphql:mutation\n#   graphql:object          \u003c========= This is what we need to run\n#   graphql:scalar\n#   graphql:union\n\n# TestUnit:\n#   test_unit:channel\n#   test_unit:controller\n#   test_unit:generator\n#   test_unit:helper\n# ...\n\n# We need to run the command mentioned above for each model. So,\nrails generate graphql:object user\nrails generate graphql:object post\n```\n\n![](./images/graphql_types.png)\n\nWith that install we should be set to building queries but we need a way to visualize it and probably do a little more easily. That's where the second gem `graphiql-rails` comes in which we added in the beginning. Its just a GUI interface which will help us run GraphQL queries\n\nNow lets update the routes file with the `GraphiQL GUI` endpoint\n```rb\n# routes.rb\nRails.application.routes.draw do\n  if Rails.env.development?\n    mount GraphiQL::Rails::Engine, at: 'graphiql', graphql_path: \"graphql#execute\"\n  end\n\n  post \"/graphql\", to: \"graphql#execute\"\nend\n```\n\n### Tweaking GraphiQL Installation\n`Note`: Sometimes the `sprockets` engine isn't enabled, and because of that, even after starting the rails server and navigating to the [graphql page](http://localhost:5000/graphiql) shows `Loading...`. To solve this issue, run the steps below:\n\n1. Enable `sprockets`\n```rb\n# config/application.rb\n# ... Some code ...\nrequire \"action_cable/engine\"\nrequire \"sprockets/railtie\" # This was commented, so uncomment it\n# ... Some code ...\n```\n\n2. Create a new file `manifest.js` inside the folder `app/assets/config` with contents\n```js\n//= link graphiql/rails/application.css\n//= link graphiql/rails/application.js\n```\n\n3. Start the Rails server\n```\nrails s --port 5000\n```\n\nOnce this is done, we should be able to open the [graphiql page](http://localhost:5000/graphiql)\n\n![](./images/graphiql_running.png)\n\n## Building GraphQL Query\n\nIf it were just a Rails application, we'd have added code to the `controller.rb` file. But remember that since this is a GraphQL project, we will have a single endpoint serving all over data. So lets start modifying the `_type.rb` files which were generated earlier.\n\nThese files will act like the models/schema for the GraphQL Application\n\n```rb\n# user_type.rb\nmodule Types\n  class UserType \u003c Types::BaseObject\n    field :id, ID, null: false\n    field :name, String, null: true\n    field :email, String, null: true\n    field :posts, [Types::PostType], null: true\n    field :posts_count, Integer, null: true\n\n    # Typical rails method returning the count\n    # of total posts for each user\n    def posts_count\n      object.posts.size\n    end\n  end\nend\n```\n\n```rb\n# posts_type.rb\nmodule Types\n  class PostType \u003c Types::BaseObject\n    field :id, Integer, null: false\n    field :title, String, null: false\n    field :body, String, null: false\n  end\nend\n```\n\nLets add queries as well. For this, update the file `query_type.rb`\n```rb\n# Define all the queries in the project\nmodule Types\n  class QueryType \u003c Types::BaseObject\n    # 1 - Adding users\n    field :users, [Types::UserType], null: false\n\n    # 1.1 Users Query\n    def users\n      User.all\n    end\n\n    # 2 - Adding one user\n    field :user, Types::UserType, null: false do\n      # Passing arguemts used to identify user\n      argument :id, ID, required: true\n    end\n\n    # 2.1 - User Query\n    def user(id:)\n      User.find(id)\n    end\n  end\nend\n```\n\nNow lets goto our [graphiql page](localhost:5000/graphiql) and type the query below\n```\n{\n  users {\n    name\n    email\n    postsCount\n  }\n}\n```\n\n![](./images/graphql_users.png)\n\nYou can also try adding `posts` with `title` and/or `body` parameters to the query and test it out\n```\n{\n  user(id:2) {\n    name\n    email\n    posts {\n      title\n      body\n    }\n  }\n}\n```\n\n![](./images/particular_post.png)\n\nNow that we're done with querying, lets start creating/modifying the data\n\n## Building GraphQL Mutations\nMutations is essentially creating or modifying the data in GraphQL. Lets go over to the `graphql/mutations`. Make sure you have a file called `base_mutations.rb`. In case if its not auto generated, just use the code below (found it in Ruby GraphQL Docs)\n```rb\n# base_mutation.rb \nmodule Mutations\n  class BaseMutation \u003c GraphQL::Schema::RelayClassicMutation\n    argument_class Types::BaseArgument\n    field_class Types::BaseField\n    input_object_class Types::BaseInputObject\n    object_class Types::BaseObject\n  end\nend\n```\n\nNow, for our users model, we want to have our own custom mutation. Lets create a new file `create_user.rb` which handles this action.\n```rb\n# create_user.rb\nclass Mutations::CreateUser \u003c Mutations::BaseMutation\n    # accepting arguments\n    argument :name, String, required: true\n    argument :email, String, required: true\n\n    # Fields to return after object creation\n    field :user, Types::UserType, null: false\n    field :errors, [String], null: false\n\n    # # The magic resolve method\n    # Its not any magic but when we have arguments specified,\n    # we need to override this method with the arguments as params,\n    # after which we run operations like saving,etc\n    def resolve(name:, email:)\n        user = User.new(name: name, email: email)\n        if user.save\n            {\n                user: user,\n                errors: []\n            }\n        else\n            {\n                user: nil,\n                errors: users.errors.full_messages\n            }\n        end\n    end\nend\n```\n\nNow that we have created our custom mutation, we need to link it to GraphQL. To do that, go to `graphql/types/mutation_type.rb` and add the field `create_user` with custom mutation `CreateUser`. \n```rb\n# mutation_type.rb\nmodule Types\n  class MutationType \u003c Types::BaseObject\n    # Field and mutation type\n    field :create_user, mutation: Mutations::CreateUser\n  end\nend\n```\n\nNow lets run the create user query\n```\nmutation {\n  createUser(input: {name: \"Yadavalli Santosh\", email: \"santosh@gmail.com\"}) {\n    user {\n      id\n      name\n      email\n      posts {\n        \n      }\n    }\n    errors\n  }\n}\n```\n\nSimilar to the mutation above, please refer to `update_user.rb` and `delete_user.rb` which are mutations for updating \u0026 deleting users respectively.\n\nThe query to update users:\n```\nmutation {\n  updateUser(input: {id: 6, name: \"Iron Man\"}) {\n    user {\n      id\n      name\n      email\n    }\n    errors\n  }\n}\n```\nThe query to delete users:\n```\nmutation {\n  deleteUser(input: {id: 7}) {\n    user {\n      id\n      name\n      email\n    }\n    errors\n  }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyvsssantosh%2Fposts_graphql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyvsssantosh%2Fposts_graphql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyvsssantosh%2Fposts_graphql/lists"}