• 一个登陆浏览api接口; 其他相关: Form_with参数的不同写法; 简单使用curl。


    eeting-up app: 完成一个需求:

    完成:https://github.com/chentianwei411/meeting-up-app


     


     

    第四步实现API接口


    Add api base and user controller 

    1. 生成controller

    • rails g controller Api::V1::BaseController
    • rails g controller Api::V1::UsersController
    • 让Api::V1::UsersController < Api::V1::BaseController

     

    2. 生成routes.rb

    namespace :api do

     namespace :v1 do

      resources :users

    ..

    3. 新建app/views/api/v1/users/show.json.jbuilder

    json.user do

     json.(@user, :id, :email, ...符号变量属性)

    end

    问题: api应该是:  Session::Options.set request.session_options[:skip] , true,不是很理解这个方法

    def destroy_session

     request.session_options[:skip] = true

    end


    Add name to user table

    rails g migration AddNameToUser name:string


     implement users can login on api(照片)

    补充:2

    先上代码图:

    分析:

    rails g controller Api::V1::Sessions

    valid_password?是Devise中的方法。用于compare传入的密码和数据库的密码是否一样。

    sign_in :user, @user是Devise中的方法。用于已经经过验证的user登陆。详细:连接

    render nothing:true, status: 401   #只返回状态吗

    此时使用Postman:

    http://localhost:3000/api/v1/sessions.json?user[email]=admin@example.org&user[password]=123123

    成功显示:{"session":{"id":1,"name":"admin@example.org","token":"nxzQkzgsbDZASfsJgsTS"}}

    status: 200 ok

    或者在terminal上curl:

    curl -i -X POST -d "user[email]=admin@example.org&user[password]=123123" http://localhost:3000/api/v1/sessions.json

    显示:

    HTTP/1.1 200 OK
    X-Frame-Options: SAMEORIGIN
    X-XSS-Protection: 1; mode=block
    X-Content-Type-Options: nosniff
    X-Download-Options: noopen
    X-Permitted-Cross-Domain-Policies: none
    Referrer-Policy: strict-origin-when-cross-origin
    Content-Type: application/json; charset=utf-8
    ETag: W/"788989157ec208ecdd233d11ddca605d"
    Cache-Control: max-age=0, private, must-revalidate
    X-Request-Id: 46292c8f-2d8e-4c2c-89ce-dff2aa83c61e
    X-Runtime: 0.161594
    Transfer-Encoding: chunked

    结果:

    {"session":{"id":1,"name":"admin@example.org","token":"nxzQkzgsbDZASfsJgsTS"}}%

    Curl(点击见一篇博客)

    基本用法:

    curl [options/ URLs]

    curl -i -X POST -d username="json" -d password="12345" http://localhost:3000/authentication

    解释:

    -i/--include        输出时包括protocol头部信息。

    -X/--require <command>  指定什么命令

    -d/--data <data>           是POST方式下传输数据。


    User can update data from api

    疑问?为什么需要自己写authenticate_user!方法?,current_user方法。

    猜测:肯能是只要api,不会加载gem❌❌❌

    先上图,然后逐句分析:

    先在BaseController中加上:  attr_accessor :current_user

    分析:

    1. token_and_options(request), 用于从请求中解析Authorization header的token和options。

    例子:Authorization: Token token="abc", nonce="def",

    返回token是'abc', options是{nonce: 'def'}

    如果token存在,返回数组[String, Hash],否则返回nil。.

    2.secure_compare() 用于比较token这个随机乱数。

    然后

    在Api::V1::UsersController中:

    before_action :authenticate_user!, only: [:update]

    def update ...end

    在对应view update.json.jbuilder加上生成的json数据。

    和全栈课Web Api设计中,4实作认证 API,6更新用户资料有类似。

    博客https://i.cnblogs.com/EditPosts.aspx?postid=9270295(不全,最好看原来的教程)


    Implement API#meetup data only return for authenticate_user

    1. rails g controller Api::V1::Meeting --no-assets

    然后加上

    before_action :authenticate_user!, only: [:update]

    def index; @meetings = Meeting.all;end

    2. 加上routes.  

    3. 在对应view加上: json.array! @meetings, :title, :description

    或者:

    json.array! @meetings do |meeting|

      json.title meeting.title

      json.description meeting.description

    end

    4. 拿token 请求meeting信息。例子:

    curl -i -X GET 
      --header "Authorization: Token token=mSDPwft9NnGYzEFLRoaP4g9aq1s+YrclxWoQ45lkubfYbnaes4kvKATgjLFNEE3jeK5hsju4hP+3LDlIbahn2w==, 
      email=bboyceo@hotmail.com" 
      http://localhost:3000//api/v1/meetups

    安装rspec,对login 接口进行测试 

    1. 添加gem 'rspec-rails'

    2.安装rails g rspec:install, 然后bin/rails spec测试一下。

    3.在.rspec中添加--format documentation, 方便查看测试结果。

    4. rails g rspec:request api_v1/session后,直接创建了requests/api_v1/session_spec.rb文件

    检查重点:

    • 回传的状态码
    • 回传的JSON
    • 检查资料是否真的被创建/修改/删除

    步骤:

    1. post(path, **args)
      • ⚠️用到了process(:post, path, **args)方法
    2. expect(response).to have_http_status(200)
    3. 在controller动作或对应的view中的JSON数据, 赋值给data = {数据...}
    4. expect(response.data).to eq(data.to_json)

    测试rails spec,成功。

    扩展:ActionController::Base < Metal

    2个基本主题:

    •  Get and Show 
    •  do and redirect 

    Requests

    每个请求,由router决定了controller和action keys。剩下的请求参数,the session, 和所有http headers会通过request accessor方法被制造出来给action,然后action被执行。

    完全的请求对象可以通过请求accessor方法使用。主要用于查询HTTP headers。例如:

    def server_ip
      location = request.env["REMOTE_ADDR"]
      render plain: "This server hosted at #{location}"
    end

    Parameters

    所有请求参数,无论是来自URL中的查询字符串还是表格通过a POST request提交的data, 都可以用params方法返回一个hash。

    例子:一个action被执行,通过/post?category=All&limit=5。 params中就会包括{"category" => "All", "limit" => 5}

    例子:类似表格

    <input type="text" name="post[name]" value="david">
    <input type="text" name="post[address]" value="hyacintvej">

    提交后会params中包括{"post" => {"name" => "david", "address" => "hyacintvej"}}

    后面还有request,包括,renders, redirects,见博客https://i.cnblogs.com/PostDone.aspx?postid=9564623&actiontip=%E5%8F%91%E5%B8%83%E6%88%90%E5%8A%9F


    Form_with:用实例对象生成html属性的写法, 与自己写html属性的区别:

    主要区别:

    1. 自己写先要用scope,这会解析成HTML动作(get, post等等),然后写清楚url
    2. 直接用实例对象,让Rails自动生成对应HTML动作和URL的话,要⚠️嵌套的结构。
    3. 嵌套结构是用Array,model: [@meeting, Comment.new]
    4. 也可以混着用:关键点是HTML动作,和url都需要正确。

    次要区别:

    1. 如果自己写html属性,需要用到xxx_tag来生成,这需要理解使用的tag的结构
    2. 使用实例对象生成属性的话,方便用参数form.XXX来生成各个HTML标签,相对容易✅。

    例子:

    <%= form_with(scope: :post,  url: meeting_comments_path(@meeting) ) do %>
     <div>
      <%= label_tag 'comment[message]',  'Message' %>  
      <%= text_area_tag('comment[message]') %>
     </div>

    等同于:

    <%= form_with(model: [@meeting, Comment.new] ) do |form| %>
     <div>
      <%= form.label :message %>
      <%= form.text_area :message %>
     </div>

    还可以混着用:(这样写✅推荐)

    <%= form_with(Comment.new, url: meeting_comments_path(@meeting) ) do |form| %>
     <div>
      <%= form.label :message %>
      <%= form.text_area :message %>
     </div>

    htmL:


  • 相关阅读:
    nefu17
    杭电1051
    杭电1050
    有关异或符号'^'在c++编程中的应用的讲解!!!
    杭电2095
    杭电2094
    关于set容器的简单讲解!!!
    拍拍开发
    收藏框架
    js form.submit() 无效
  • 原文地址:https://www.cnblogs.com/chentianwei/p/9550829.html
Copyright © 2020-2023  润新知