C
C#2y ago
chimera

❔ Designing an api that can create "fields" with different values

Hi, so I am creating a feature in my API where the user can create kind of a Form, and the user can create some fields with different value types. The field types are bool, string, date, decimal, and a list, where the important things are the name. The thing i find difficult is how to store the different values in the best way. I have several different thought, ranging from every field type having it's own class, inheriting from one Field class with common properties, to just store it in one class type, and shoving every possible type in a string, and having an enum tell me what type it is, and just convert it back. This will make it hard to make any search meaningful however. Last thought i had is to have one class type and having it have a BoolValue, StringValue and so on. I feel like there is some better OOP way to do this that i ain't seeing. This also needs to work with Entity Framework 🙂
16 Replies
Florian Voß
Florian Voß2y ago
I might be missunderstanding but why not create a type that represents the result of this Form and assign each input of the form to a property of that type using events? the properties will have basic types like string, DateTime, decimal, list each representing an input
chimera
chimera2y ago
I may have been to vague, but the form will be custom. So the user can design it themselves. Therefore i wanna a class that represents the form name etc. and connect a list to that with the available fields to fill
Tvde1
Tvde12y ago
you'd go with something like this:
class Form
{
List<FormField> Fields;
}
class FormField
{
int Id;
string Name;
string DataType;
}
class Form
{
List<FormField> Fields;
}
class FormField
{
int Id;
string Name;
string DataType;
}
and a reponse like
class FormResponse
{
List<FormFieldResponse> Fields;
}
class FormFieldResponse
{
int FieldId;
string Value;
}
class FormResponse
{
List<FormFieldResponse> Fields;
}
class FormFieldResponse
{
int FieldId;
string Value;
}
It's all generic now
chimera
chimera2y ago
So you would serialize everything to a string value? dates etc?
Tvde1
Tvde12y ago
ye depending on the DataType the front-end would show a date picker/ text box/ checkbox, and the back-end would use it to cast Value to the correct value
chimera
chimera2y ago
Yea that was my thinking as well. Only thing i was thinking is the search would be slow on a db?
Tvde1
Tvde12y ago
depends on how you want to search you could also serialize the form to JSON in your db if your db has good JSON support
chimera
chimera2y ago
If i want to search in a date range? Using regular Azure Relational DB
Tvde1
Tvde12y ago
try it out, and if it doesn't perform, then pick something else ^^ I've made systems exactly like this if you need it to perform: use several tables: * Forms * Form Field Definitions * Form Submissions * Form Submission Field Values
chimera
chimera2y ago
Good idea So Form Submission Field Values is still just string?
Tvde1
Tvde12y ago
yeah probably or you make several columns of different data types and fill in one
chimera
chimera2y ago
Cool Thanks alot 🙂
Tvde1
Tvde12y ago
Tvde1
Tvde12y ago
@startuml

entity Form
{
+Id
+Name
}

entity FormFieldDefinition
{
+Id
+FK FormId
+Name
+DataType
}

entity FormResponse
{
+Id
+FK FormId
+UserId
}

entity FormResponseFieldValue
{
+FK FormResponseId
+FK FormFieldDefinitionId
+Value
}

Form ||-o{ FormFieldDefinition
FormResponse }o-up-|| Form
FormResponse ||-o{ FormResponseFieldValue
FormResponseFieldValue }o-up-|| FormFieldDefinition

@enduml
@startuml

entity Form
{
+Id
+Name
}

entity FormFieldDefinition
{
+Id
+FK FormId
+Name
+DataType
}

entity FormResponse
{
+Id
+FK FormId
+UserId
}

entity FormResponseFieldValue
{
+FK FormResponseId
+FK FormFieldDefinitionId
+Value
}

Form ||-o{ FormFieldDefinition
FormResponse }o-up-|| Form
FormResponse ||-o{ FormResponseFieldValue
FormResponseFieldValue }o-up-|| FormFieldDefinition

@enduml
The plantuml :) have fun! I've implemented something exactly like this, and it works like a charm
chimera
chimera2y ago
Really nice to know that it works for someone in prod 🙂
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.