-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Implement JSON API #230
base: master
Are you sure you want to change the base?
Conversation
* Update Ruby to 2.5.1 * Replace factory_girl -> factory_bot * Add JWT * Generate markdown API docs only * Errors refactor * Update README and remove unused gems
After upgrading rails to version 5, database_cleaner became redundant * https://github.com/teamcapybara/capybara#transactions-and-database-setup * thoughtbot/suspenders@44e984f
@@ -55,39 +54,6 @@ Status of the API could be checked at [http://localhost:5000/docs](http://localh | |||
* `bin/ci` - should be used in the CI or locally | |||
* `bin/server` - to run server locally |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add bin/doc
script description here?
Also we can remove bin/foreman
.
* [knock](https://github.com/nsarno/knock) – seamless JWT authentication | ||
* [puma](https://github.com/puma/puma) as Rails web server | ||
* [rack-cors](https://github.com/cyu/rack-cors) for [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) | ||
* [responders](https://github.com/plataformatec/responders) - DRY controllers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do not use them as I see. Is it planned for future using in admin panel for example?
module V1 | ||
class UsersController < V1::BaseController | ||
expose :user | ||
expose :users, -> { User.all } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add pagination?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can consider https://github.com/davidcelis/api-pagination gem to mimic pagination like User.page(params[:page][:number]).per(params[:page][:size])
in controller as I think.
config.log_level = :info | ||
# Use the lowest log level to ensure availability of diagnostic information | ||
# when problems arise. | ||
config.log_level = :debug |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use :info
log level in production env to reduce logs size? If not then we can comment or remove this line (it is default).
@@ -1,52 +1,51 @@ | |||
# Skeleton for new Rails 4 application for REST API | |||
# Skeleton for new Rails 5 application for JSON API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we update doc/README_TEMPLATE.md
accordingly?
context "with invalid password" do | ||
let(:password) { "invalid" } | ||
|
||
example "Create Token with invalid password" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here...
context "with invalid id" do | ||
let(:id) { 0 } | ||
|
||
example "Retrive User with invalid id" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here...
@@ -0,0 +1,12 @@ | |||
# rubocop:disable RSpec/EmptyExampleGroup | |||
shared_examples "API endpoint with authorization" do | |||
context "without authorization headers", document: false do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
document: false
does not work on context
as I know. It should be written like:
context "..." do
example "...", document: false do
do_request
...
end
end
it "fails" do | ||
interactor.run | ||
expect(context).to be_failure | ||
expect(context.message).to eql(params[:message]) if params |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our interactor returns code
on failure. Should we check it here?
@@ -0,0 +1,6 @@ | |||
shared_examples "success interactor" do | |||
it "success" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it "succeeds"
skip_before_action :authenticate_user! | ||
|
||
def create | ||
result = CreateJwt.call(authentication_params) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we really introduce custom logic for generating a token? It is already provided by a gem. Also creating a separate JwtToken model not necessary. Looks like you are doing it only to response in JSON API format, but maybe we can return token here in JSON API manually?
class V1::TokensController < Knock::AuthTokenController
skip_before_action :verify_authenticity_token, only: :create
def create
render json: response_data, status: :created
end
private
def response_data
{ data: { id: auth_token.token, type: "tokens" } }
end
def entity_class
User
end
def auth_params
jsonapi_params(only: %i[email password])
end
end
In this case, we can remove JwtToken model, CreateJwt interactor and JwtTokenSerializer. Any thoughts?
devise :database_authenticatable, :registerable, | ||
:recoverable, :trackable, :validatable | ||
validates :email, presence: true | ||
validates :password, length: { minimum: 6 } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To update a user's attribute he always needs to pass a password. Was it intended? Looks like if you need to update a full_name for example, you don't need to provide a password.
validates :password, length: { minimum: 6 }, if: -> { new_record? || password_digest_changed? }
Implement JSON API
Token request:
Users requests (specify token from Tokens request):
Closes #208