# How to avoid repeating code between back-, middle-, and front-ends?

**URL:** <https://discourse.julialang.org/t/how-to-avoid-repeating-code-between-back-middle-and-front-ends/59697>\
**Category:** Web Stack\
**Tags:** question\
**Created:** [April 20, 2021, 9:26pm UTC](https://discourse.julialang.org/t/how-to-avoid-repeating-code-between-back-middle-and-front-ends/59697 "2021-04-20T21:26:42Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [April 20, 2021, 9:26pm UTC](https://discourse.julialang.org/t/how-to-avoid-repeating-code-between-back-middle-and-front-ends/59697/1 "2021-04-20T21:26:42Z")

</div>

When building a full-stack app, I find it frustrating to define basically 3 nearly identical types:

1. What I consider the main struct: defining the logic of the type disregarding any GUI/DB needs. This is the struct you’d define normally. This struct would contain only the most basic fields needed to define it “in real life” (e.g. a `User` will have `name`, `email`, and `password`). Methods associated with it would only deal with actions that have to do with what it actually is.
2. The back-end struct: same as in #1 but for the database, with the obligatory `id` and maybe public `id` for associations with other entities. Methods with this one would be CRUD.
3. The front-end struct: Again, same as #1 but for the GUI. User-facing with some additional checks and validations.

**How do you cope with this duplicity (triplicity)?** It isn’t the end of the world, but I keep thinking that if and when I’ll want to change some property of one of the types (probably #1) I’ll need to manually propagate (read replicate) the change to all 3 (nearly identical) implementations.

The specific tools I’m using right now are Genie, Stipple, SQLite, SearchLightMySQL (and later postgres).

Thanks for any insight!

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [April 20, 2021, 11:53pm UTC](https://discourse.julialang.org/t/how-to-avoid-repeating-code-between-back-middle-and-front-ends/59697/2 "2021-04-20T23:53:51Z")

</div>

Share the business object in 1) with the other two tiers. The other tiers can wrap it as a member of a struct that adds tier-dependent information.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [April 22, 2021, 6:46am UTC](https://discourse.julialang.org/t/how-to-avoid-repeating-code-between-back-middle-and-front-ends/59697/3 "2021-04-22T06:46:02Z")

</div>

I do not use `Genie`, but in [ZulipReminderBot.jl](https://github.com/Arkoniak/ZulipReminderBot.jl) I’ve used the following approach:

1. Define business logic in usual structure
2. All table related information (like table name, primary key, autoincrement property and so on) define as functions over struct type. The main idea is that all information of this kind is the same for all instances of this type so should be defined only once. Later in code I just use these functions at places where it is necessary.

You probably can simulate the same behaviour with `getproperty` method if Genie.jl allows to use arbitrary structures.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [April 22, 2021, 6:54am UTC](https://discourse.julialang.org/t/how-to-avoid-repeating-code-between-back-middle-and-front-ends/59697/4 "2021-04-22T06:54:23Z")

</div>

Thank you for your input!  
So, I had a similar idea, but for `id` this is problematic/impossible:  
Say I do this:

```julia
abstract type HasID end

struct User <: HasID
  name::String
  email::String
end

Base.getproperty(x::HasID, field::Symbol) = field === :id ? hash(x) : getfield(x, field)

```

and then I have this for free:

```julia
julia> a = User("a", "b")
User("a", "b")

julia> a.name
"a"

julia> a.email
"b"

julia> a.id
0xc537b8713bce82db

```

the `id` is then no longer immutable (if a user changes their name/email), and I can’t _assign_ an ID to a user, only read it. So the DB can no longer assign IDs.

How did you solve that, or did I misunderstand you?

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [April 22, 2021, 7:02am UTC](https://discourse.julialang.org/t/how-to-avoid-repeating-code-between-back-middle-and-front-ends/59697/5 "2021-04-22T07:02:01Z")

</div>

Ah, you are right of course. I was thinking about table properties, but surely there are per-object differences in db and business data representation.

In my case I just added `id` to business struct. I guess in more general case one should do something like

```julia
struct User
  name::String
  email::String
end

struct DBRow{T}
  id::Int
  val::T
end

```

and have smart enough ORM/Database which can represent flat table structure in this form, so upon select you get object of the type `DBRow{User}` and you can always extract `User` values with `x.val`.

This problem looks suspiciously similar to inheritance problem in Julia, so it probably have similar ways of solving.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [April 22, 2021, 7:17am UTC](https://discourse.julialang.org/t/how-to-avoid-repeating-code-between-back-middle-and-front-ends/59697/6 "2021-04-22T07:17:42Z")

</div>

I’m trying to implement @essenciary’s solution suggested in [this issue](https://github.com/GenieFramework/Genie.jl/issues/359#issuecomment-823955946) for my own needs now, but it would be great to see some MWE in practice: how exactly we connect the DB (and GUI) to the business data representation.
