From ee76e0c69b31528a223c57830ed178969b29b80b Mon Sep 17 00:00:00 2001 From: Shishir Kakaraddi Date: Sat, 3 Nov 2018 12:11:56 -0700 Subject: [PATCH 1/8] bump up version to 1.5 --- lib/fast_jsonapi/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fast_jsonapi/version.rb b/lib/fast_jsonapi/version.rb index c9c4c7ab..12442c14 100644 --- a/lib/fast_jsonapi/version.rb +++ b/lib/fast_jsonapi/version.rb @@ -1,3 +1,3 @@ module FastJsonapi - VERSION = "1.4" + VERSION = "1.5" end From a160d6746f2f35e157b42cd6d797a74bed1405f0 Mon Sep 17 00:00:00 2001 From: Manoj M J Date: Thu, 15 Nov 2018 13:40:18 +0530 Subject: [PATCH 2/8] Fix Documentation of Meta Per Resource Some part of the documentation for this got removed during last merge, so fixing it. --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 53c8bfa7..77cbf3bf 100644 --- a/README.md +++ b/README.md @@ -276,7 +276,12 @@ This will create a `self` reference for the relationship, and a `related` link f ### Meta Per Resource For every resource in the collection, you can include a meta object containing non-standard meta-information about a resource that can not be represented as an attribute or relationship. + + ```ruby +class MovieSerializer + include FastJsonapi::ObjectSerializer + meta do |movie| { years_since_release: Date.current.year - movie.year From e0228dacdca7599cf4c7a83cc37d28568eef9a09 Mon Sep 17 00:00:00 2001 From: Manoj M J Date: Wed, 14 Nov 2018 19:58:14 +0530 Subject: [PATCH 3/8] Add documentation on how to use helper methods in serializers --- README.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/README.md b/README.md index 77cbf3bf..0ef40239 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Fast JSON API serialized 250 records in 3.01 ms * [Conditional Attributes](#conditional-attributes) * [Conditional Relationships](#conditional-relationships) * [Sparse Fieldsets](#sparse-fieldsets) + * [Using helper methods](#using-helper-methods) * [Contributing](#contributing) @@ -449,6 +450,68 @@ serializer = MovieSerializer.new(movie, { fields: { movie: [:name] } }) serializer.serializable_hash ``` +### Using helper methods + +You can mix-in code from another ruby module into your serializer class to reuse functions across your app. + +Since a serializer is evaluated in a the context of a `class` rather than an `instance` of a class, you need to make sure that your methods act as `class` methods when mixed in. + + +##### Using ActiveSupport::Concern + +``` ruby + +module AvatarHelper + extend ActiveSupport::Concern + + class_methods do + def avatar_url(user) + user.image.url + end + end +end + +class UserSerializer + include FastJsonapi::ObjectSerializer + + include AvatarHelper # mixes in your helper method as class method + + set_type :user + + attributes :name, :email + + attribute :avatar do |user| + avatar_url(user) + end +end + +``` + +##### Using Plain Old Ruby + +``` ruby +module AvatarHelper + def avatar_url(user) + user.image.url + end +end + +class UserSerializer + include FastJsonapi::ObjectSerializer + + extend AvatarHelper # mixes in your helper method as class method + + set_type :user + + attributes :name, :email + + attribute :avatar do |user| + avatar_url(user) + end +end + +``` + ### Customizable Options Option | Purpose | Example From bc04aeec02a55cef5b2bc71776c2440958b47452 Mon Sep 17 00:00:00 2001 From: Amy Sutedja Date: Fri, 11 Jan 2019 14:28:31 -0800 Subject: [PATCH 4/8] New pluralize_type option in serializers --- lib/fast_jsonapi/object_serializer.rb | 21 ++++++- lib/fast_jsonapi/serialization_core.rb | 1 + .../object_serializer_class_methods_spec.rb | 59 +++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/lib/fast_jsonapi/object_serializer.rb b/lib/fast_jsonapi/object_serializer.rb index b8a24183..724da12d 100644 --- a/lib/fast_jsonapi/object_serializer.rb +++ b/lib/fast_jsonapi/object_serializer.rb @@ -153,6 +153,17 @@ def set_key_transform(transform_name) end end + def pluralize_type(pluralize) + self.pluralized_type = pluralize + + # ensure that the record type is correctly transformed + if record_type + set_type(record_type) + elsif reflected_record_type + set_type(reflected_record_type) + end + end + def run_key_transform(input) if self.transform_method.present? input.to_s.send(*@transform_method).to_sym @@ -161,13 +172,21 @@ def run_key_transform(input) end end + def run_key_pluralization(input) + if self.pluralized_type + input.to_s.pluralize.to_sym + else + input.to_sym + end + end + def use_hyphen warn('DEPRECATION WARNING: use_hyphen is deprecated and will be removed from fast_jsonapi 2.0 use (set_key_transform :dash) instead') set_key_transform :dash end def set_type(type_name) - self.record_type = run_key_transform(type_name) + self.record_type = run_key_transform(run_key_pluralization(type_name)) end def set_id(id_name = nil, &block) diff --git a/lib/fast_jsonapi/serialization_core.rb b/lib/fast_jsonapi/serialization_core.rb index 200af9b3..7d2bcf29 100644 --- a/lib/fast_jsonapi/serialization_core.rb +++ b/lib/fast_jsonapi/serialization_core.rb @@ -16,6 +16,7 @@ class << self :cachable_relationships_to_serialize, :uncachable_relationships_to_serialize, :transform_method, + :pluralized_type, :record_type, :record_id, :cache_length, diff --git a/spec/lib/object_serializer_class_methods_spec.rb b/spec/lib/object_serializer_class_methods_spec.rb index 205f6452..97c92418 100644 --- a/spec/lib/object_serializer_class_methods_spec.rb +++ b/spec/lib/object_serializer_class_methods_spec.rb @@ -486,4 +486,63 @@ def year_since_release_calculator(release_year) end end end + + describe '#pluralize_type' do + subject(:serializable_hash) { MovieSerializer.new(movie).serializable_hash } + + before do + MovieSerializer.pluralize_type pluralize + end + + after do + MovieSerializer.pluralize_type nil + MovieSerializer.set_type :movie + end + + context 'when pluralize is true' do + let(:pluralize) { true } + + it 'returns correct hash which type equals pluralized value' do + expect(serializable_hash[:data][:type]).to eq :movies + end + end + + context 'when pluralize is false' do + let(:pluralize) { false } + + it 'returns correct hash which type equals non-pluralized value' do + expect(serializable_hash[:data][:type]).to eq :movie + end + end + end + + describe '#pluralize_type after #set_type' do + subject(:serializable_hash) { MovieSerializer.new(movie).serializable_hash } + + before do + MovieSerializer.set_type type_name + MovieSerializer.pluralize_type true + end + + after do + MovieSerializer.pluralize_type nil + MovieSerializer.set_type :movie + end + + context 'when sets singular type name' do + let(:type_name) { :film } + + it 'returns correct hash which type equals transformed set_type value' do + expect(serializable_hash[:data][:type]).to eq :films + end + end + + context 'when sets plural type name' do + let(:type_name) { :films } + + it 'returns correct hash which type equals transformed set_type value' do + expect(serializable_hash[:data][:type]).to eq :films + end + end + end end From d81f8bbfded482a995e30a4fc1289f730817b8a4 Mon Sep 17 00:00:00 2001 From: Amy Sutedja Date: Fri, 11 Jan 2019 15:43:10 -0800 Subject: [PATCH 5/8] Pluralization support for relationships --- lib/fast_jsonapi/object_serializer.rb | 1 + lib/fast_jsonapi/relationship.rb | 16 ++++- .../object_serializer_pluralization_spec.rb | 61 +++++++++++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 spec/lib/object_serializer_pluralization_spec.rb diff --git a/lib/fast_jsonapi/object_serializer.rb b/lib/fast_jsonapi/object_serializer.rb index 724da12d..c3bc5dce 100644 --- a/lib/fast_jsonapi/object_serializer.rb +++ b/lib/fast_jsonapi/object_serializer.rb @@ -269,6 +269,7 @@ def create_relationship(base_key, relationship_type, options, block) block ), record_type: options[:record_type] || run_key_transform(base_key_sym), + pluralize_type: options[:pluralize_type], object_method_name: options[:object_method_name] || name, object_block: block, serializer: compute_serializer_name(options[:serializer] || base_key_sym), diff --git a/lib/fast_jsonapi/relationship.rb b/lib/fast_jsonapi/relationship.rb index 7a038de7..89e4d1af 100644 --- a/lib/fast_jsonapi/relationship.rb +++ b/lib/fast_jsonapi/relationship.rb @@ -1,12 +1,13 @@ module FastJsonapi class Relationship - attr_reader :key, :name, :id_method_name, :record_type, :object_method_name, :object_block, :serializer, :relationship_type, :cached, :polymorphic, :conditional_proc, :transform_method, :links, :lazy_load_data + attr_reader :key, :name, :id_method_name, :record_type, :pluralized_type, :object_method_name, :object_block, :serializer, :relationship_type, :cached, :polymorphic, :conditional_proc, :transform_method, :links, :lazy_load_data def initialize( key:, name:, id_method_name:, record_type:, + pluralize_type:, object_method_name:, object_block:, serializer:, @@ -21,7 +22,8 @@ def initialize( @key = key @name = name @id_method_name = id_method_name - @record_type = record_type + @pluralized_type = pluralize_type + @record_type = run_key_pluralization(record_type) @object_method_name = object_method_name @object_block = object_block @serializer = serializer @@ -77,7 +79,7 @@ def ids_hash_from_record_and_relationship(record, params = {}) def id_hash_from_record(record, record_types) # memoize the record type within the record_types dictionary, then assigning to record_type: - associated_record_type = record_types[record.class] ||= run_key_transform(record.class.name.demodulize.underscore) + associated_record_type = record_types[record.class] ||= run_key_transform(run_key_pluralization(record.class.name.demodulize.underscore)) id_hash(record.id, associated_record_type) end @@ -116,5 +118,13 @@ def run_key_transform(input) input.to_sym end end + + def run_key_pluralization(input) + if self.pluralized_type + input.to_s.pluralize.to_sym + else + input.to_sym + end + end end end diff --git a/spec/lib/object_serializer_pluralization_spec.rb b/spec/lib/object_serializer_pluralization_spec.rb new file mode 100644 index 00000000..f2c19944 --- /dev/null +++ b/spec/lib/object_serializer_pluralization_spec.rb @@ -0,0 +1,61 @@ +require 'spec_helper' + +describe FastJsonapi::ObjectSerializer do + class Author + attr_accessor :id, :name + end + + class Book + attr_accessor :id, :name, :authors, :references + + def author_ids + authors.map(&:id) + end + end + + class Song + attr_accessor :id, :name, :artist + end + + class BookSerializer + include FastJsonapi::ObjectSerializer + attributes :name + set_key_transform :dash + has_many :authors, pluralize_type: true + has_many :references, polymorphic: true, pluralize_type: true + pluralize_type true + end + + let(:book) do + book = Book.new + book.id = 1 + book.name = 'Monstrous Regiment' + book + end + + let(:author) do + author = Author.new + author.id = 1 + author.name = 'Terry Pratchett' + author + end + + let(:song) do + song = Song.new + song.id = 1 + song.name = 'Sweet Polly Oliver' + song + end + + context 'when serializing id and type of polymorphic relationships' do + it 'should return correct type when transform_method is specified' do + book.authors = [author] + book.references = [song] + book_hash = BookSerializer.new(book).to_hash + record_type = book_hash[:data][:relationships][:authors][:data][0][:type] + expect(record_type).to eq 'authors'.to_sym + record_type = book_hash[:data][:relationships][:references][:data][0][:type] + expect(record_type).to eq 'songs'.to_sym + end + end +end From b13cc36dd744f23b159918e752820982349e78e6 Mon Sep 17 00:00:00 2001 From: Amy Sutedja Date: Fri, 11 Jan 2019 15:58:02 -0800 Subject: [PATCH 6/8] Pluralization information in readme --- README.md | 126 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 80 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 0ef40239..1462dbce 100644 --- a/README.md +++ b/README.md @@ -18,32 +18,32 @@ Fast JSON API serialized 250 records in 3.01 ms # Table of Contents -* [Features](#features) -* [Installation](#installation) -* [Usage](#usage) - * [Rails Generator](#rails-generator) - * [Model Definition](#model-definition) - * [Serializer Definition](#serializer-definition) - * [Object Serialization](#object-serialization) - * [Compound Document](#compound-document) - * [Key Transforms](#key-transforms) - * [Collection Serialization](#collection-serialization) - * [Caching](#caching) - * [Params](#params) - * [Conditional Attributes](#conditional-attributes) - * [Conditional Relationships](#conditional-relationships) - * [Sparse Fieldsets](#sparse-fieldsets) - * [Using helper methods](#using-helper-methods) -* [Contributing](#contributing) - +- [Features](#features) +- [Installation](#installation) +- [Usage](#usage) + - [Rails Generator](#rails-generator) + - [Model Definition](#model-definition) + - [Serializer Definition](#serializer-definition) + - [Object Serialization](#object-serialization) + - [Compound Document](#compound-document) + - [Key Transforms](#key-transforms) + - [Pluralize Type](#pluralize-type) + - [Collection Serialization](#collection-serialization) + - [Caching](#caching) + - [Params](#params) + - [Conditional Attributes](#conditional-attributes) + - [Conditional Relationships](#conditional-relationships) + - [Sparse Fieldsets](#sparse-fieldsets) + - [Using helper methods](#using-helper-methods) +- [Contributing](#contributing) ## Features -* Declaration syntax similar to Active Model Serializer -* Support for `belongs_to`, `has_many` and `has_one` -* Support for compound documents (included) -* Optimized serialization of compound documents -* Caching +- Declaration syntax similar to Active Model Serializer +- Support for `belongs_to`, `has_many` and `has_one` +- Support for compound documents (included) +- Optimized serialization of compound documents +- Caching ## Installation @@ -62,6 +62,7 @@ $ bundle install ## Usage ### Rails Generator + You can use the bundled generator if you are using the library inside of a Rails project: @@ -106,11 +107,13 @@ movie ### Object Serialization #### Return a hash + ```ruby hash = MovieSerializer.new(movie).serializable_hash ``` #### Return Serialized JSON + ```ruby json_string = MovieSerializer.new(movie).serialized_json ``` @@ -148,11 +151,11 @@ json_string = MovieSerializer.new(movie).serialized_json } } } - ``` ### Key Transforms -By default fast_jsonapi underscores the key names. It supports the same key transforms that are supported by AMS. Here is the syntax of specifying a key transform + +By default fast_jsonapi underscores the key names. It supports the same key transforms that are supported by AMS. Here is the syntax of specifying a key transform: ```ruby class MovieSerializer @@ -161,7 +164,8 @@ class MovieSerializer set_key_transform :camel end ``` -Here are examples of how these options transform the keys + +Here are examples of how these options transform the keys. ```ruby set_key_transform :camel # "some_key" => "SomeKey" @@ -170,10 +174,34 @@ set_key_transform :dash # "some_key" => "some-key" set_key_transform :underscore # "some_key" => "some_key" ``` +### Pluralize Type + +By default fast_jsonapi does not pluralize type names. You can turn pluralization on using this syntax: + +```ruby +class AwardSerializer + include FastJsonapi::ObjectSerializer + belongs_to :actor + pluralize_type true # "award" => "awards" +end +``` + +Relationship types are not automatically pluralized, even when their base types have `pluralize_type` set. Pluralization can be enabled in the relationship definition. + +```ruby +class ActorSerializer + include FastJsonapi::ObjectSerializer + has_many :awards, pluralize_type: true # "award" => "awards" +end +``` + +The most common use case for this feature is to easily migrate from serialization engines that pluralize by default, such as AMS. + ### Attributes -Attributes are defined in FastJsonapi using the `attributes` method. This method is also aliased as `attribute`, which is useful when defining a single attribute. -By default, attributes are read directly from the model property of the same name. In this example, `name` is expected to be a property of the object being serialized: +Attributes are defined in FastJsonapi using the `attributes` method. This method is also aliased as `attribute`, which is useful when defining a single attribute. + +By default, attributes are read directly from the model property of the same name. In this example, `name` is expected to be a property of the object being serialized: ```ruby class MovieSerializer @@ -222,6 +250,7 @@ end ``` ### Links Per Object + Links are defined in FastJsonapi using the `link` method. By default, links are read directly from the model property of the same name. In this example, `public_url` is expected to be a property of the object being serialized. You can configure the method to use on the object for example a link with key `self` will get set to the value returned by a method called `url` on the movie object. @@ -293,7 +322,7 @@ end ### Compound Document -Support for top-level and nested included associations through ` options[:include] `. +Support for top-level and nested included associations through `options[:include]`. ```ruby options = {} @@ -337,10 +366,11 @@ options[:is_collection] was introduced to be able to have precise control this behavior - `nil` or not provided: will try to autodetect single vs collection (please, see notes above) -- `true` will always treat input resource as *collection* -- `false` will always treat input resource as *single object* +- `true` will always treat input resource as _collection_ +- `false` will always treat input resource as _single object_ ### Caching + Requires a `cache_key` method be defined on model: ```ruby @@ -514,18 +544,18 @@ end ### Customizable Options -Option | Purpose | Example ------------- | ------------- | ------------- -set_type | Type name of Object | ```set_type :movie ``` -key | Key of Object | ```belongs_to :owner, key: :user ``` -set_id | ID of Object | ```set_id :owner_id ``` or ```set_id { |record| "#{record.name.downcase}-#{record.id}" }``` -cache_options | Hash to enable caching and set cache length | ```cache_options enabled: true, cache_length: 12.hours, race_condition_ttl: 10.seconds``` -id_method_name | Set custom method name to get ID of an object (If block is provided for the relationship, `id_method_name` is invoked on the return value of the block instead of the resource object) | ```has_many :locations, id_method_name: :place_ids ``` -object_method_name | Set custom method name to get related objects | ```has_many :locations, object_method_name: :places ``` -record_type | Set custom Object Type for a relationship | ```belongs_to :owner, record_type: :user``` -serializer | Set custom Serializer for a relationship | ```has_many :actors, serializer: :custom_actor``` or ```has_many :actors, serializer: MyApp::Api::V1::ActorSerializer``` -polymorphic | Allows different record types for a polymorphic association | ```has_many :targets, polymorphic: true``` -polymorphic | Sets custom record types for each object class in a polymorphic association | ```has_many :targets, polymorphic: { Person => :person, Group => :group }``` +| Option | Purpose | Example | +| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| set_type | Type name of Object | `set_type :movie` | +| key | Key of Object | `belongs_to :owner, key: :user` | +| set_id | ID of Object | `set_id :owner_id` or `set_id { |record| "#{record.name.downcase}-#{record.id}" }` | +| cache_options | Hash to enable caching and set cache length | `cache_options enabled: true, cache_length: 12.hours, race_condition_ttl: 10.seconds` | +| id_method_name | Set custom method name to get ID of an object (If block is provided for the relationship, `id_method_name` is invoked on the return value of the block instead of the resource object) | `has_many :locations, id_method_name: :place_ids` | +| object_method_name | Set custom method name to get related objects | `has_many :locations, object_method_name: :places` | +| record_type | Set custom Object Type for a relationship | `belongs_to :owner, record_type: :user` | +| serializer | Set custom Serializer for a relationship | `has_many :actors, serializer: :custom_actor` or `has_many :actors, serializer: MyApp::Api::V1::ActorSerializer` | +| polymorphic | Allows different record types for a polymorphic association | `has_many :targets, polymorphic: true` | +| polymorphic | Sets custom record types for each object class in a polymorphic association | `has_many :targets, polymorphic: { Person => :person, Group => :group }` | ### Instrumentation @@ -542,8 +572,9 @@ require 'fast_jsonapi/instrumentation' ``` The two instrumented notifcations are supplied by these two constants: -* `FastJsonapi::ObjectSerializer::SERIALIZABLE_HASH_NOTIFICATION` -* `FastJsonapi::ObjectSerializer::SERIALIZED_JSON_NOTIFICATION` + +- `FastJsonapi::ObjectSerializer::SERIALIZABLE_HASH_NOTIFICATION` +- `FastJsonapi::ObjectSerializer::SERIALIZED_JSON_NOTIFICATION` It is also possible to instrument one method without the other by using one of the following require statements: @@ -553,15 +584,18 @@ require 'fast_jsonapi/instrumentation/serialized_json' ``` Same goes for the Skylight integration: + ```ruby require 'fast_jsonapi/instrumentation/skylight/normalizers/serializable_hash' require 'fast_jsonapi/instrumentation/skylight/normalizers/serialized_json' ``` ## Contributing + Please see [contribution check](https://github.com/Netflix/fast_jsonapi/blob/master/CONTRIBUTING.md) for more details on contributing ### Running Tests + We use [RSpec](http://rspec.info/) for testing. We have unit tests, functional tests and performance tests. To run tests use the following command: ```bash @@ -584,4 +618,4 @@ rspec spec --tag performance:true Join the Netflix Studio Engineering team and help us build gems like this! -* [Senior Ruby Engineer](https://jobs.netflix.com/jobs/864893) +- [Senior Ruby Engineer](https://jobs.netflix.com/jobs/864893) From 22e2b2ca0851cb1e15dc738a045998db5d95822e Mon Sep 17 00:00:00 2001 From: Amy Sutedja Date: Mon, 14 Jan 2019 14:41:52 -0800 Subject: [PATCH 7/8] Pluralize state correctly inherits --- lib/fast_jsonapi/object_serializer.rb | 1 + .../lib/object_serializer_inheritance_spec.rb | 21 +++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/fast_jsonapi/object_serializer.rb b/lib/fast_jsonapi/object_serializer.rb index c3bc5dce..fd9184e8 100644 --- a/lib/fast_jsonapi/object_serializer.rb +++ b/lib/fast_jsonapi/object_serializer.rb @@ -118,6 +118,7 @@ def inherited(subclass) subclass.cachable_relationships_to_serialize = cachable_relationships_to_serialize.dup if cachable_relationships_to_serialize.present? subclass.uncachable_relationships_to_serialize = uncachable_relationships_to_serialize.dup if uncachable_relationships_to_serialize.present? subclass.transform_method = transform_method + subclass.pluralized_type = pluralized_type subclass.cache_length = cache_length subclass.race_condition_ttl = race_condition_ttl subclass.data_links = data_links.dup if data_links.present? diff --git a/spec/lib/object_serializer_inheritance_spec.rb b/spec/lib/object_serializer_inheritance_spec.rb index beb74872..a26abdad 100644 --- a/spec/lib/object_serializer_inheritance_spec.rb +++ b/spec/lib/object_serializer_inheritance_spec.rb @@ -95,13 +95,23 @@ class EmployeeSerializer < UserSerializer has_one :account end + class LegacyUserSerializer < UserSerializer + pluralize_type true + end + + class LegacyEmployeeSerializer < LegacyUserSerializer + attributes :location + attributes :compensation + + has_one :account + end + it 'sets the correct record type' do expect(EmployeeSerializer.reflected_record_type).to eq :employee expect(EmployeeSerializer.record_type).to eq :employee end context 'when testing inheritance of attributes' do - it 'includes parent attributes' do subclass_attributes = EmployeeSerializer.attributes_to_serialize superclass_attributes = UserSerializer.attributes_to_serialize @@ -157,12 +167,15 @@ class EmployeeSerializer < UserSerializer end end - context 'when test inheritence of other attributes' do - - it 'inherits the tranform method' do + context 'when testing inheritence of other attributes' do + it 'inherits the transform method' do EmployeeSerializer expect(UserSerializer.transform_method).to eq EmployeeSerializer.transform_method end + it 'inherits pluralized_type' do + LegacyEmployeeSerializer + expect(LegacyUserSerializer.pluralized_type).to eq LegacyEmployeeSerializer.pluralized_type + end end end From 4a0ef07b8097ffa7011e71db6cbdc7791d0a199e Mon Sep 17 00:00:00 2001 From: Amy Sutedja Date: Fri, 5 Apr 2019 15:33:21 -0700 Subject: [PATCH 8/8] Fix readme syntax --- README.md | 100 ++++++++++++++++++++++++------------------------------ 1 file changed, 45 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 1462dbce..97af42fe 100644 --- a/README.md +++ b/README.md @@ -18,32 +18,33 @@ Fast JSON API serialized 250 records in 3.01 ms # Table of Contents -- [Features](#features) -- [Installation](#installation) -- [Usage](#usage) - - [Rails Generator](#rails-generator) - - [Model Definition](#model-definition) - - [Serializer Definition](#serializer-definition) - - [Object Serialization](#object-serialization) - - [Compound Document](#compound-document) - - [Key Transforms](#key-transforms) - - [Pluralize Type](#pluralize-type) - - [Collection Serialization](#collection-serialization) - - [Caching](#caching) - - [Params](#params) - - [Conditional Attributes](#conditional-attributes) - - [Conditional Relationships](#conditional-relationships) - - [Sparse Fieldsets](#sparse-fieldsets) - - [Using helper methods](#using-helper-methods) -- [Contributing](#contributing) +* [Features](#features) +* [Installation](#installation) +* [Usage](#usage) + * [Rails Generator](#rails-generator) + * [Model Definition](#model-definition) + * [Serializer Definition](#serializer-definition) + * [Object Serialization](#object-serialization) + * [Compound Document](#compound-document) + * [Key Transforms](#key-transforms) + * [Pluralize Type](#pluralize-type) + * [Collection Serialization](#collection-serialization) + * [Caching](#caching) + * [Params](#params) + * [Conditional Attributes](#conditional-attributes) + * [Conditional Relationships](#conditional-relationships) + * [Sparse Fieldsets](#sparse-fieldsets) + * [Using helper methods](#using-helper-methods) +* [Contributing](#contributing) + ## Features -- Declaration syntax similar to Active Model Serializer -- Support for `belongs_to`, `has_many` and `has_one` -- Support for compound documents (included) -- Optimized serialization of compound documents -- Caching +* Declaration syntax similar to Active Model Serializer +* Support for `belongs_to`, `has_many` and `has_one` +* Support for compound documents (included) +* Optimized serialization of compound documents +* Caching ## Installation @@ -62,7 +63,6 @@ $ bundle install ## Usage ### Rails Generator - You can use the bundled generator if you are using the library inside of a Rails project: @@ -107,13 +107,11 @@ movie ### Object Serialization #### Return a hash - ```ruby hash = MovieSerializer.new(movie).serializable_hash ``` #### Return Serialized JSON - ```ruby json_string = MovieSerializer.new(movie).serialized_json ``` @@ -151,10 +149,10 @@ json_string = MovieSerializer.new(movie).serialized_json } } } + ``` ### Key Transforms - By default fast_jsonapi underscores the key names. It supports the same key transforms that are supported by AMS. Here is the syntax of specifying a key transform: ```ruby @@ -164,7 +162,6 @@ class MovieSerializer set_key_transform :camel end ``` - Here are examples of how these options transform the keys. ```ruby @@ -198,10 +195,9 @@ end The most common use case for this feature is to easily migrate from serialization engines that pluralize by default, such as AMS. ### Attributes +Attributes are defined in FastJsonapi using the `attributes` method. This method is also aliased as `attribute`, which is useful when defining a single attribute. -Attributes are defined in FastJsonapi using the `attributes` method. This method is also aliased as `attribute`, which is useful when defining a single attribute. - -By default, attributes are read directly from the model property of the same name. In this example, `name` is expected to be a property of the object being serialized: +By default, attributes are read directly from the model property of the same name. In this example, `name` is expected to be a property of the object being serialized: ```ruby class MovieSerializer @@ -250,7 +246,6 @@ end ``` ### Links Per Object - Links are defined in FastJsonapi using the `link` method. By default, links are read directly from the model property of the same name. In this example, `public_url` is expected to be a property of the object being serialized. You can configure the method to use on the object for example a link with key `self` will get set to the value returned by a method called `url` on the movie object. @@ -322,7 +317,7 @@ end ### Compound Document -Support for top-level and nested included associations through `options[:include]`. +Support for top-level and nested included associations through ` options[:include] `. ```ruby options = {} @@ -366,11 +361,10 @@ options[:is_collection] was introduced to be able to have precise control this behavior - `nil` or not provided: will try to autodetect single vs collection (please, see notes above) -- `true` will always treat input resource as _collection_ -- `false` will always treat input resource as _single object_ +- `true` will always treat input resource as *collection* +- `false` will always treat input resource as *single object* ### Caching - Requires a `cache_key` method be defined on model: ```ruby @@ -544,18 +538,18 @@ end ### Customizable Options -| Option | Purpose | Example | -| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -| set_type | Type name of Object | `set_type :movie` | -| key | Key of Object | `belongs_to :owner, key: :user` | -| set_id | ID of Object | `set_id :owner_id` or `set_id { |record| "#{record.name.downcase}-#{record.id}" }` | -| cache_options | Hash to enable caching and set cache length | `cache_options enabled: true, cache_length: 12.hours, race_condition_ttl: 10.seconds` | -| id_method_name | Set custom method name to get ID of an object (If block is provided for the relationship, `id_method_name` is invoked on the return value of the block instead of the resource object) | `has_many :locations, id_method_name: :place_ids` | -| object_method_name | Set custom method name to get related objects | `has_many :locations, object_method_name: :places` | -| record_type | Set custom Object Type for a relationship | `belongs_to :owner, record_type: :user` | -| serializer | Set custom Serializer for a relationship | `has_many :actors, serializer: :custom_actor` or `has_many :actors, serializer: MyApp::Api::V1::ActorSerializer` | -| polymorphic | Allows different record types for a polymorphic association | `has_many :targets, polymorphic: true` | -| polymorphic | Sets custom record types for each object class in a polymorphic association | `has_many :targets, polymorphic: { Person => :person, Group => :group }` | +Option | Purpose | Example +------------ | ------------- | ------------- +set_type | Type name of Object | ```set_type :movie ``` +key | Key of Object | ```belongs_to :owner, key: :user ``` +set_id | ID of Object | ```set_id :owner_id ``` or ```set_id { |record| "#{record.name.downcase}-#{record.id}" }``` +cache_options | Hash to enable caching and set cache length | ```cache_options enabled: true, cache_length: 12.hours, race_condition_ttl: 10.seconds``` +id_method_name | Set custom method name to get ID of an object (If block is provided for the relationship, `id_method_name` is invoked on the return value of the block instead of the resource object) | ```has_many :locations, id_method_name: :place_ids ``` +object_method_name | Set custom method name to get related objects | ```has_many :locations, object_method_name: :places ``` +record_type | Set custom Object Type for a relationship | ```belongs_to :owner, record_type: :user``` +serializer | Set custom Serializer for a relationship | ```has_many :actors, serializer: :custom_actor``` or ```has_many :actors, serializer: MyApp::Api::V1::ActorSerializer``` +polymorphic | Allows different record types for a polymorphic association | ```has_many :targets, polymorphic: true``` +polymorphic | Sets custom record types for each object class in a polymorphic association | ```has_many :targets, polymorphic: { Person => :person, Group => :group }``` ### Instrumentation @@ -572,9 +566,8 @@ require 'fast_jsonapi/instrumentation' ``` The two instrumented notifcations are supplied by these two constants: - -- `FastJsonapi::ObjectSerializer::SERIALIZABLE_HASH_NOTIFICATION` -- `FastJsonapi::ObjectSerializer::SERIALIZED_JSON_NOTIFICATION` +* `FastJsonapi::ObjectSerializer::SERIALIZABLE_HASH_NOTIFICATION` +* `FastJsonapi::ObjectSerializer::SERIALIZED_JSON_NOTIFICATION` It is also possible to instrument one method without the other by using one of the following require statements: @@ -584,18 +577,15 @@ require 'fast_jsonapi/instrumentation/serialized_json' ``` Same goes for the Skylight integration: - ```ruby require 'fast_jsonapi/instrumentation/skylight/normalizers/serializable_hash' require 'fast_jsonapi/instrumentation/skylight/normalizers/serialized_json' ``` ## Contributing - Please see [contribution check](https://github.com/Netflix/fast_jsonapi/blob/master/CONTRIBUTING.md) for more details on contributing ### Running Tests - We use [RSpec](http://rspec.info/) for testing. We have unit tests, functional tests and performance tests. To run tests use the following command: ```bash @@ -618,4 +608,4 @@ rspec spec --tag performance:true Join the Netflix Studio Engineering team and help us build gems like this! -- [Senior Ruby Engineer](https://jobs.netflix.com/jobs/864893) +* [Senior Ruby Engineer](https://jobs.netflix.com/jobs/864893)