让我们在Hanami中尝试实施GraphQL API

我要在Hanami中实现GraphQL API。

创建项目

mkdir hanami-blog
cd hanami-blog
# frozen_string_literal: true
source "https://rubygems.org"

gem "hanami", '1.0.0'
bundle install
bundle exec hanami new . --application-name=api 
bundle install

创建模型

bundle exec hanami generate model user
bundle exec hanami generate model post
Hanami::Model.migration do
  change do
    create_table :users do
      primary_key :id

      column :name , String, null: false
      column :email, String, null: false

      column :created_at, DateTime, null: false
      column :updated_at, DateTime, null: false
    end
  end
end
Hanami::Model.migration do
  change do
    create_table :posts do
      primary_key :id
      foreign_key :user_id, :users, on_delete: :cascade, null: false

      column :title  , String, null: false
      column :content, String, null: true

      column :created_at, DateTime, null: false
      column :updated_at, DateTime, null: false
    end
  end
end
bundle exec hanami db prepare 

创建”Type”

+ gem 'graphql', '1.6.4'
bundle install
mkdir -p apps/api/types
      load_paths << [
        'controllers',
        'views',
+       'types'
      ]
UserType = GraphQL::ObjectType.define do
  name 'User'
  description 'User'
  field :id, types.ID
  field :name, types.String
  field :postss, types[!PostType]
end
PostType = GraphQL::ObjectType.define do
  name 'Post'
  description 'Post'
  field :id     , types.ID
  field :title  , types.String
  field :content, types.String
  field :user   , UserType do
    resolve ->(obj, _, _) { UserRepository.new.find(obj.user_id) }
  end
end
require_relative 'user_type'
require_relative 'post_type'

QueryType = GraphQL::ObjectType.define do
  name 'Query'
  description 'The query root for this schema'

  field :user do
    type UserType
    argument :id, !types.ID
    resolve ->(_, args, _) { UserRepository.new.find(args[:id]) }
  end

  field :post do
    type PostType
    argument :id, !types.ID
    resolve ->(_, args, _) { PostRepository.new.find(args[:id]) }
  end
end
require_relative 'query_type'

HanamiBlogSchema = GraphQL::Schema.define(query: QueryType)
class PostRepository < Hanami::Repository
  def posts_by_user(user)
    posts.where(user_id: user.id)
  end
end

创建控制器

root to: "graphql#show"
module Api::Controllers::Graphql
  class Show
    include Api::Action

    def call(params)
      query_variables = params[:vairables] || {}
      self.body = JSON.generate(HanamiBlogSchema.execute(params[:query], variables: query_variables))
    end
  end
end

创造测试数据

bundle exec hanami c
irb(main):002:0> user = UserRepository.new.create name: "foo", email: "foo@exsample.com"
irb(main):005:0> PostRepository.new.create user_id: user.id, title: "aaa", contest: "AAA"
irb(main):006:0> PostRepository.new.create user_id: user.id, title: "bbb", contest: "BBB"

试一试

bundle exec hanami s
curl -XGET -d 'query={ user(id: 1) { name email posts {id title} } }' http://localhost:2300/ | jq .
{
  "data": {
    "user": {
      "name": "foo",
      "email": "foo@exsample.com",
      "posts": [
        {
          "id": "1",
          "title": "aaa"
        },
        {
          "id": "2",
          "title": "bbb"
        }
      ]
    }
  }
}
curl -XGET -d 'query={ post(id: 1) { title user { name } } }' http://localhost:2300/ | jq . 
{
  "data": {
    "post": {
      "title": "aaa",
      "user": {
        "name": "foo"
      }
    }
  }
}

以上是关于Hanami x GraphQL的细分领域和需求的问题,希望能对您有所帮助。

请参考

广告
将在 10 秒后关闭
bannerAds