craigspaeth / griffin

A WIP Elixir(script) framework
MIT License
0 stars 0 forks source link

Goals #2

Open craigspaeth opened 6 years ago

craigspaeth commented 6 years ago

The 🔑 to high-quality software is a programmer being able to rapidly—test, change, understand the effects of, deploy, monitor production usage of, and rollback—code. Elixir as a language/VM should help this with solid testing tools, functional patterns, immutability/minimized side-effects, hot code reload/deploying, let-it-crash fault tolerance. I'm going to bet that in the majority of cases the language/VM alone can be leveraged to allow one to accidentally accomplish an acceptable level of performance, fault-tolerance, error handling, modularity, robustness, etc. So this framework should 80% of the time make tradeoffs in favor of simpler/easier patterns and rapid development experience.

craigspaeth commented 6 years ago

We should practice extreme minimalism + extensibility with this. There're too many problems to solve as it is, so let's just focus providing the bear-minimum API surface area that heavily leverages pure-ish functions, pipelines, and data-based DSLs to be extensible.

Extreme minimalism

Models

Views

Controller

Slightly less extreme

✅ Winner because clear separation of concerns and more practical

Data Models

View Models

Views

Controller

craigspaeth commented 6 years ago
def model, do: [
  author: [
    id: :id!,
    first_name: :string,
    last_name: :string,
    posts: [:"[post!]!",
      "The list of Posts by this author",
      &resolve_posts/3
    ]
  ],
  post: [
    id: :id!,
    title: :string,
    author: :author,
    votes: :int
  ],
  query: [
    posts: [:"[post]", &resolve_posts/3]
  ],
  mutation: [
    upvote_post: [[post_id: :id!], :post, &resolve_upvote_post/3]
  ],
  schema: [
    query: :query,
    mutation: :mutation
  ]
]

DSL is like...

field_name: [
  args (keywords),
  return type (atom),
  description (string),
  resolver (func)
]
or
field_name: return type (atom)
craigspaeth commented 6 years ago

How the controller works:

Server:

Plug middleware...

  1. Finds :route in events
  2. Runs the corresponding func with VM.model(), ctx
  3. Send VM.model(state) to view

Client:

  1. Griffin script loads code
  2. Runs emit(:dom_ready)
  3. Mounts view
  4. Runs emit(:route, url)