美文网首页
使用Grape和Grape-Entity构建一个简单的API——

使用Grape和Grape-Entity构建一个简单的API——

作者: 花前山谷 | 来源:发表于2019-11-28 19:33 被阅读0次

    这是最后一部分,我们构建了两个API路由,我们可以返回一个book列表,还可以通过id返回特定book的信息。还用了entities获取我们想要的数据,但这还不够。
    所以在最后的这一部分,我们将会看到如何使用entities的嵌套来获取想要的数据。
    我们的API目录现在是这个样子滴:

    .app
     .api
      .book_store 
       .entities
        - book.rb
       .v1
        - books.rb
      - base.rb   
    

    添加flows资源

    我们有两个模型,book和flow。一个book下有多个flows。所以我们需要在book资源中嵌套flows。
    在 books.rb 文件中中,我们的最后一个API后添加如下代码:

    resource :flows do
      desc 'Create a flow.'
      params do
        requires :flow, type: Hash do
          requires :newStock, type: Integer, desc: 'New Stock.'
          requires :previousStock, type: Integer, desc: 'Previous Stock.'
        end
      end
      post do
        @book = Book.find(params[:id])
        @flow = Flow.new(params[:flow])
        @flow = [@book](http://twitter.com/book).flows.create!(params[:flow])
        @book.update(stock: @flow.newStock)
      end
    end
    

    最后我们的book.rb会变成这个样子:

    module BookStore
      module V1
        class Books < Grape::API
          version 'v1', using: :path
          format :json
          prefix :api
          resource :books do
    
            desc 'Return list of books'
            get do
              books = Book.all
              present books
            end
    
            desc 'Return a specific book'
            route_param :id do
              get do
                book = Book.find(params[:id])
                present book, with: BookStore::Entities::Book
              end
              resource :flows do
                desc 'Create a flow.'
                params do
                  requires :flow, type: Hash do
                    requires :newStock, type: Integer, desc: 'New Stock.'
                    requires :previousStock, type: Integer, desc: 'Previous Stock.'
                  end
                end
                post do
                  @book = Book.find(params[:id])
                  @flow = Flow.new(params[:flow])
                  @flow = @book.flows.create!(params[:flow])
                  @book.update(stock: @flow.newStock)
                end
              end
            end
          end
        end
      end
    end
    

    再检查一下我们的API路由:

    rails grape:routes
    
    GET  |  /api/:version/books(.json)  |  v1  |  Return list of books
    GET  |  /api/:version/books/:id(.json) |  v1  |  Return a specific book
    POST  |  /api/:version/books/:id/flows(.json) |  v1  |  Create a flow.
    

    现在我们创建了一个新的路由,允许我们对某一特定book添加flow。


    添加flow entity

    如果现在尝试对某一book创建flow是可以成功的,但是我们通过地址http://localhost:3000/api/v1/books/1并不能访问book下的flow。因此实现这个功能我们需要添加一个flow entity。

    touch app/api/book_store/entities/flow.rb
    

    文件中加入如下代码:

    module BookStore
      module Entities
        class Flow < Grape::Entity
          expose :newStock
          expose :previousStock
        end
      end
    end
    

    现在我们添加好了flow entity,接下来我们要在book entity中添加新的代码,打开app/api/book_store/entities/book.rb文件并且加入如下代码:

    expose :flows, using: BookStore::Entities::Flow
    

    现在我们在浏览器访问 http://localhost:3000/api/v1/books/1

    {"isbn":8880548713,"title":"Telekinesis","stock":4234,"flows":[{"newStock":4314,"previousStock":234},{"newStock":1585,"previousStock":1762},{"newStock":2537,"previousStock":2913},{"newStock":626,"previousStock":1788},{"newStock":1435,"previousStock":2011}]}
    

    现在我们来添加book列表的entity

    touch app/api/book_store/entities/index.rb
    
    module BookStore
      module Entities
        class Index < Grape::Entity
           expose :isbn
           expose :title
           expose :stock
        end
      end
    end
    

    并将entity应用到api当中:

    present books, with: BookStore::Entities::Index
    

    新建flow

    我们构建了一个方法去新建flow,但是我们仍没有去添加它。我们需要在终端通过curl请求添加。

    curl -i -X POST -H 'Content-Type: application/json' -d '{ "flow": { "newStock": 10, "previousStock": 12 } }' http://localhost:3000/api/v1/books/1/flows
    

    如果不出意料的话在终端中会返回如下类似的结果:

    HTTP/1.1 201 Created
    Content-Type: application/json
    ETag: W/"b5bea41b6c623f7c09f1bf24dcae58eb"
    Cache-Control: max-age=0, private, must-revalidate
    X-Request-Id: 152aafc8-5c74-4fdf-b12e-d2c6937ff20b
    X-Runtime: 0.011693
    Content-Length: 4
    

    当然也可以使用postman来测试我们的api,这样你就创建了第一个flow啦😊~


    END

    相关文章

      网友评论

          本文标题:使用Grape和Grape-Entity构建一个简单的API——

          本文链接:https://www.haomeiwen.com/subject/zufiwctx.html