Object-oriented design that can be used when you want to return a response in form format

background

I am in charge of the back end of the system currently under development, and implemented something like "returning some API responses in form format". I thought that the design used at this time was versatile, so I decided to write an article.

The essential meaning is different, but depending on the point of view, I think it looks like an adapter in the design pattern. I'm not sure if it's correct. ..

The language is ruby ​​and the framework is rails.

Requirements

Tests table

column Mold
id int8
first varchar(255)
second varchar(255)

Suppose you have a table like the one above and you want to return one record in the JSON response format below.

{
	"form_items" : [
		{
			"item_name" : "first",
			"value" : "hoge" #value in first column
		},
		{
			"item_name" : "second",
			"value" : "fuga" #second column value
		}
	]
}

In the actual system, not only item_name and value but also metadata etc. are included and it has a complicated structure, but this time it is a simple design for convenience. Assuming that the number of columns will increase in the future and the elements of the array of form_items will be proportional to each column.

Design and implementation

We have prepared 5 classes.

The third is the class that defines the Field. I am creating a FieldBase class as an abstract class.

At first glance you may be wondering why you designed it this way, but given the increased amount of columns and metadata that accompanies them, I thought it was safe.


class FirstField < FieldBase
  COLUMN_NAME = 'first'
end

class SecondField < FieldBase
  COLUMN_NAME = 'second'
end

class Base
  def initialize(record)
    @record = record
  end

  def value
    @record.send(self.class::COLUMN_NAME)
  end
end

The 4th and 5th will be explained as a set

First, the FormItem class is created to hold a set of item_name and value as an instance. Specifically, you can see it by looking at the fifth class.

class FormItem
  attr_reader :item_name, :value

  def initialize(field_instance)
    @item_name = field_instance.class::COLUMN_NAME
    @value = field_instance.value
  end
end

The fifth is a class that creates an array of form_item

class FormItemList
  attr_reader :form_items

  def initialize(record)
    @form_items = []

    #Below form_The order of items is directly linked to the order of forms sent as a response
    form_item(FirstField.new(record))
    form_item(SecondField.new(record))
  end

  private

  def form_item(field_instance)
    @form_items += [FormItem.new(field_instance)]
  end
end

After that, if you call it with controller as follows, you can get an array whose elements are objects made into form format.

record = Test.first
form_items = FormItemList.new(record).form_items

pp form_items
# => [FormItem instance created from FirstField instance, FormItem instance created from FirstField instance]

At this point, just serialize the objects in the array to json.

There are various serialize methods, so I won't explain them.

Summary

I don't think I'm getting much benefit from a small number of columns or metadata, but I think it's good that it's easier to customize as it grows!

I recently started Twitter, so please follow me!

Recommended Posts

Object-oriented design that can be used when you want to return a response in form format
[Android] I want to create a ViewPager that can be used for tutorials
How to make a key pair of ecdsa in a format that can be read by Java
When you want to check whether the contents of a property can be converted to a specific type
How to override in a model unit test so that Faker can be used to generate random values
A story that could be implemented neatly by using polymorphism when you want to express two types of data in one table
When you want to bind InputStream in JDBI3
A note when you want Tuple in Java
What to do when you want to delete a migration file that is "NO FILE"
Write a class that can be ordered in Java
When you want to dynamically replace Annotation in Java8
Convenient shortcut keys that can be used in Eclipse
Syntax and exception occurrence conditions that can be used when comparing with null in Java
When you want to change the wording to be displayed when making a select box from enum
Create a page control that can be used with RecyclerView
Create a jar file that can be executed in Gradle
Introduction to Rakefile that can be done in about 10 minutes
Find a Switch statement that can be converted to a Switch expression
[Spring Dtata JPA] How to deal with the problem that DB change cannot be detected when you want to process API synchronously with a single thread in Spring Boot.
[Swift] When you want to know if the number of characters in a String matches a certain number ...
A collection of patterns that you want to be aware of so as not to complicate the code
ProxyFactory is convenient when you want to test AOP in Spring!
Summary of ORM "uroboroSQL" that can be used in enterprise Java
I made a question that can be used for a technical interview
Setting that converts to binding.pry when you type pry in VScode
SwiftUI View that can be used in combination with other frameworks
When you receive a call, send an SMS to that number
[Java 8] Until converting standard input that can be used in coding tests into a list or array
Are you still exhausted to implement the search function? Gem'ransack' that can be implemented in an instant
The first thing to do when you want to be happy with Heroku on GitHub with Eclipse in Java
A memo when you want to clear the time part of the calendar
[Rails] I want to send data of different models in a form
When you want Rails to disable a session for a specific controller only
Library summary that seems to be often used in recent Android development (2019/11)
[Rails] "pry-rails" that can be used when saving with the create method
A memo that enabled VS Code + JUnit 5 to be used on Windows 10
[Swift] If you want to use a URL that includes Japanese, use addingPercentEncoding.
[Swift] Color Picker that can be used with copy and paste (palette that allows you to freely select colors)
Object-oriented that can be understood by fairies
Technology excerpt that can be used for creating EC sites in Java training
When is it said that you can use try with a Swift error?
I made a THETA API client that can be used for plug-in development
When you want to notify an error somewhere when using graphql-spring-boot in Spring Boot
Android Studio memo that you want to display Toast characters in large size
Code used when you want to process Json with only the standard library in Java (improved version) gson unnecessary
Summary of copy and paste commands used when you want to delete the cache in iOS application development anyway
[Ruby] When you want to assign the result obtained by conditional branching to a variable and put it in the argument
[Rails] What to do when you want to generate an error that cannot be destory when foreign key restrictions are applied
I want you to put the story that the error was solved when you stabbed the charger in the corner of your head