stas/jsonapi.rb

What am I missing in using jsonapi.rb to render json api?

AfolabiOlaoluwa opened this issue · 8 comments

Expected Behavior

Expected to return all the list of items in the database with a GET request.

Actual Behavior/Response

{
  "errors": [
    {
      "status": "500",
      "source": null,
      "title": "Internal Server Error",
      "detail": null
    }
  ]
}

Steps to Reproduce the Problem

  1. app/controller/api/v1
module Api
  module V1
    class TransactionsController < ApplicationController
      def index
        render jsonapi: Transaction.all.load
      end

      def show; end

      private

      def create_action_params
        params.require(:transaction).permit(permitted_transaction_attributes)
      end
    end
  end
end
  1. transaction.rb
# frozen_string_literal: true

class Transaction < ApplicationRecord
  belongs_to :user
end
  1. app/serializers/transaction_serializer.rb
# frozen_string_literal: true

class TransactionSerializer
  include JSONAPI::Serializer

  attributes :tx_uuid, :user_id, :input_amount, :input_currency, :output_amount, :output_currency, :tx_date
end
  1. routes.rb
# frozen_string_literal: true

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :transactions, only: %i[index show]
    end
  end
end

Specifications

  • Version: gem 'jsonapi.rb', '~> 2.0'
  • Ruby version: Ruby 3.0.0
mculp commented

Well, it looks like your code raised an exception.

You'll need to paste the stacktrace from the exception, otherwise, we'll just be guessing :)

Well, I reproduced it to Encoding::UndefinedConversionError ("\xEF" from ASCII-8BIT to UTF-8)
by changing the code in the index to render json: Transaction.all and moved the code off namespaces.

How do you fix Encoding::UndefinedConversionError ("\xEF" from ASCII-8BIT to UTF-8)???

app/controllers/transactions_controller.rb:7:in `index'
Started GET "/transactions" for 127.0.0.1 at 2022-05-19 19:49:28 +0100
  [1m[35m (0.8ms)[0m  [1m[34mSELECT sqlite_version(*)[0m
  [1m[36mActiveRecord::SchemaMigration Pluck (2.7ms)[0m  [1m[34mSELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC[0m
Processing by TransactionsController#index as */*
  Parameters: {"transaction"=>{}}
  [1m[36mUser Load (4.0ms)[0m  [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?[0m  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/application_controller.rb:10:in `current_user'
  [1m[36mTransaction Load (2.7ms)[0m  [1m[34mSELECT "transactions".* FROM "transactions"[0m
  ↳ app/controllers/transactions_controller.rb:6:in `index'
Completed 500 Internal Server Error in 300ms (ActiveRecord: 21.6ms | Allocations: 11431)
  
Encoding::UndefinedConversionError ("\xEF" from ASCII-8BIT to UTF-8):
  
app/controllers/transactions_controller.rb:7:in `index'
stas commented

@AfolabiOlaoluwa render json: Transaction.all is not related to this gem, you'd have to use render jsonapi: Transaction.all instead.

render jsonapi: Transaction.all returns the same error now. Encoding::UndefinedConversionError ("\xEF" from ASCII-8BIT to UTF-8). I used render json just to be able to pinpoint what the problem is.

stas commented

@AfolabiOlaoluwa looks like you're storing some data as ASCII, but Ruby is trying to use it as UTF-8. Please review the data you have in the database, or update the default encoding you're using.

Thank you @stas. I am able to fix the problem now. I knew that was asking my to convert some of my data to UTF-8 to be able to pull it but I didn't know where to do it in my codebase.

What happened was that I have a t.binary datatype on my database. Therefore, in the controller that makes the GET request, I passed in # encoding: UTF-8 and it worked.

# encoding: UTF-8 
# frozen_string_literal: true

module Api
  module V1
    class TransactionsController < ApplicationController
    end 
  end
end

However @stas, I believe using render jsonapi: the_resource_here should be able to say what the problem was. I certainly didn't have to use render json: before I could know what the problem was. I believe something should be fixed on the library itself.

stas commented

However @stas, I believe using render jsonapi: the_resource_here should be able to say what the problem was. I certainly didn't have to use render json: before I could know what the problem was. I believe something should be fixed on the library itself.

Well, you're probably using the error handling mixin, that's why you got a nice error response, instead of a backtrace dump:
https://github.com/stas/jsonapi.rb#error-handling

If you remove the include JSONAPI::Errors you'll get a normal backtrace.

I'm glad it worked out for you though 🙌