Problem Statement
I’m Newbie in Rails and following this tutorial for setting up JWT based authentication in API, and working on an existing web application that uses Devise. My task at the moment is to add a JSON API to the application.
This rails project works fine for a web applications. However, Incase of API I’m getting empty resource while I still have value in params.
Environment
rails (6.1.4)
devise (4.8.0)
devise-jwt (0.9.0)
warden (1.2.9)
warden-jwt_auth (0.6.0)
Controller & Route
app/controllers/api/v1/users/registrations_controller.rb
class Api::V1::Users::RegistrationsController < Devise::RegistrationsController
respond_to :json
skip_before_action :verify_authenticity_token
# POST /resource
def create
super
end
private
def respond_with(resource, _opts = {})
if resource.persisted?
render json: {
status: { code: 200, message: "Signed up sucessfully." },
data: UserSerializer.new(resource).serializable_hash[:data][:attributes]
}
else
render json: {
status: { message: "User couldn't be created successfully. #{resource.errors.full_messages.to_sentence}" }
}, status: :unprocessable_entity
end
end
end
config/routes.rb
# For Web
devise_for :users, controllers: { registrations: "registrations" }
# Authentication
devise_scope :user do
get "/login" => "devise/sessions#new", as: :login
get "/logout" => "sessions#destroy", :as => :logout
get "/signup" => "registrations#new", :as => :signup
scope "my" do
get "profile", to: "registrations#edit"
put "profile/update", to: "registrations#update"
end
end
authenticated :user do
resources :dashboard, only: [:index] do
collection do
get :home
end
end
end
unauthenticated do
as :user do
root to: "devise/sessions#new", as: :unauthenticated_root
end
end
# For API
namespace :api do
namespace :v1 do
devise_for :users, path: '', path_names: {
sign_in: 'login',
sign_out: 'logout',
registration: 'signup'
},
controllers: {
sessions: 'api/v1/users/sessions',
registrations: 'api/v1/users/registrations'
}
end
end
Debugging information
app/controllers/api/v1/users/registrations_controller.rb
| 66: private
| 67: def respond_with(resource, _opts = {})
| 68: byebug
| => 69: if resource.persisted?
| 70: render json: {
| 71: status: { code: 200, message: "Signed up sucessfully." },
| 72: data: UserSerializer.new(resource).serializable_hash[:data][:attributes]
| 73: }
| (byebug) resource
| #<User
id: nil,
email: "",
first_name: "",
last_name: "",
role: "member",
created_at: nil,
updated_at: nil,
jti: nil
>
| (byebug) params
| #<ActionController::Parameters
{
"email"=>"test@test.com",
"first_name"=>"John",
"last_name"=>"Wick",
"password"=>"password",
"controller"=>"api/v1/users/registrations",
"action"=>"create",
"registration"=>{
"email"=>"test@test.com",
"first_name"=>"John",
"last_name"=>"Wick",
"password"=>"password"
}
} permitted: false>
- Request
curl -X POST \
http://127.0.0.1:3000/api/v1/signup \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-d '{
"email": "test@test.com",
"first_name": "John",
"last_name": "Wick",
"password": "password"
}'
- Response
{
"status": {
"message": "User couldn't be created successfully. Email can't be blank and Password can't be blank"
}
}