Contexts - a barrier too high for newbies?

If I understand this correctly, the problem is that newbies don’t get best practices and find somewhat hard to comply.
But isn’t it that the reason why they are newbies and we set up best practices ?

When I first bumped into Rails I was already an experienced programmer, but I had been working on .net and weborms for years and it was really confusing for me at first.
Rails wasn’t easy at all for newbies, but it was opinionated and that made feel other’s people code familiar and helped expanding the knowledge.
What’s easy now has been hard at the beginning.

Practice makes you perfect, I strongly believe in the value of enforcing good behaviours instead of being too permissive and allowing the big ball of mud to prevail.

5 Likes

Given the questions I see here and elsewhere, while contexts may be a stumbling block for some people, the real barrier appears to be Ecto. The hardest questions, often with the fewest answers, tend to be ones about Ecto.

Querying structured data is not the easiest thing in the world, and trying to create a nice abstraction between the storage system and your application is not easy. Ecto itself has been evolving rapidly, and so there are a few More Than One Way To Do Things, and many rough edges to be found (I created a pull request for one of those just 3 days ago).

Ecto is awesome, but it isn’t perfectly easy. And the amount of high quality examples out there is not … encouraging. Most cover the simple things (as someone else noted, real world use cases are rather more complex). … yet we don’t really hear toooo much here about the complexity of Ecto and how to make it more approachable.

So for me, worry over context is a sort of classic “bikeshedding”: contexts are easy to spot as a bump because they are new. New things without clear and unambiguous (perceived) benefits are often perceived as bad, or at least uncomfortable, at the start. Contexts are also somewhat trivial: they don’t REALLY introduce a new concept to the language or even the framework. You could have been doing something like contexts before, and you can ignore them now. So they aren’t really … critical. Contexts are also easy to understand and have been highly exposed.

So there are lots of discussions about them. Losing too much energy over that discussion is probably not useful, especially when there are bigger fish to fry out there such as Ecto.

What I think is likely to resolve the issue:

  • time (as @josevalim noted already)
  • a clearer statement and understanding among us developers what the purpose and benefits of contexts really are
  • some nice examples / tutorials to show the path (as others have noted, having trailblazers to follow helps a lot more than documentation and marketing alone)

This is not to say that contexts are not a possible problem for newcomers. They may well be. And if people are saying that they are a problem for themselves, I think we have to accept that as true.

What we don’t know is what % of people coming to Phoenix are finding contexts an issue, for how long that persists, if it is a blocker, and/or what other issues are more important to them. Personally, I would very much appreciate a developer feedback survey that we could use to gather some data to understand what really is going on :slight_smile:

8 Likes

Phoenix isn’t Rails. Rails is good for what it’s good and it gives the biggest head start for some kinds of projects. New programmers can get most done with Rails with these kinds of projects. Phoenix is like Rails for programmers looking for an easy entry into the world of concurrency and microservices (separation of concerns). It is very obvious that these two concepts will be key strengths for programming languages in the near future. With other languages you need to do so much planning and analysis to properly separate concerns and get maximum computational power, while with Elixir you get it out of the box.

I think that Phoenix is like Rails for concurrency/microservices. Add on top of that pattern matching and functional programming which are massively taking over each programming field (mobile, front end…) I think that Phoenix/Elixir is in the best possible position.

4 Likes

I’m agree with topic starter - contexts in the way they are now are terrible. On other hand, some other way may be godsend. Also, for me, contexts make much more sense for controllers (e.g. separate context for public area, for account’s private zone, admin area), for various helper modules/services, for wrapper methods around schemas but not for schemas itself

1 Like

Would you mind elaborating on this a little bit? What about them do you think is terrible? What would you try to do to improve them?

2 Likes

Well, don’t know, proved to be hard question.
Also, see comment above - how about putting other parts into context.
Also, like mentioned earlier, something like Post.Post "posts" isnt really useful :confused: maybe shared/global context? (Going to become garbage bin though)

Also, atm it’s really hard to decide how an app should be split into contexts. Imo that’s the most important point and everything should start from here. After all the videos, blog posts, discussions i don’t know how to apply contexts correctly (and it should be obvious, for the sake of humanity and developers). Current approach do not solve this

4 Likes

some nice examples / tutorials to show the path

This is really important!

When I was working through Ecto’s concepts and mechanisms, it didn’t really click for me – until I came across some examples by Geoffrey Lessel. In particular his talk at Lonestar ElixirConf 2017 was the key to me:

Using Ecto outside of Phoenix

He also has some great examples on his blog as well, such as:

1 Like

IMO, usually when you start building an app your Context is going to be the initial purpose of your app. Whatever your MVP design goal was to begin with. The place where I think contexts confuse people is in trying to over-engineer it too early.

In a simple web app, for example, I’d start out with 2 contexts:

  1. Public
  2. Login (includes sign up / registration / login / tracking / security / etc)

As Login context is a pretty natural initial separation. Public is my “dumping ground” where app stuff goes. As you work and start to notice patterns in your application where separate grouping makes more sense, create that separation.

A ruby site that I worked on a few years ago provided a really good example for this. It was a secondary sales site for a niche market that had auctions, classifieds, advertising, login/registration, forums, data imports (from a legacy site), user messaging and a ton of anti-fraud stuff. Within the monolith you had all of these things in the system. Auctions and Classifieds both used Products, but the transaction process for each was different and the subset of related information and rules were both just on top of each other. Advertising had a system for users to buy and preview ads for different parts of the site, while the logic to properly display them in a fast, balanced way and while tracking them was a beast in and of itself.

As it stands now, that site basically has a User and Product models that are at least 1000 lines long as well as a ton of smaller tables, relational tables, etc with models to match. Each one has well over a dozen associations that go down a chain of associations which are a mile long. This was a project that I jumped into after another team had developed it for 8 months and the entire time I worked on it (little over a year), I was still constantly digging through the code trying to figure out what went with what. Contexts would have been absolutely amazing for that project.

Anyway, I say all of that to say this: don’t overthink it at the beginning. When you have an app idea, your initial goal is probably “the context” you just need a name for that. I go with Public because it gives me a clear implication of when something might not belong in there (behaviors that differ when users are logged in, when tooling interfaces are involved, etc). Login and Public are a really good place to start. Then just move things out when a better arrangement becomes clear.

The best thing about it is that you don’t have to decided “Do users belong here or here?” because they might belong in both in some form and contexts let you do that, really easily.

3 Likes

I’am also a bit confused how to correctly deal with contexts in Phoenix 1.3 applications.

I’ve watched several screen casts, read some blog posts on how to correctly structure an application with contexts. But until now, I don’t know if it’s the intended/best way to have e.g. a single user schema, maybe in the “Account” context, while other contexts referencing to this schema or to have an independent user schema per context (each referencing to a single “real” database table) which needs to interact with users.

Just assume that a user’s table might have 100 columns eventually with little related one off data points or belongs to associations. No one part of your application needs all of them.

Unless you have an admin section that gives full access to every field, you probably only need a small subset of the users table in any given context. Outside of registration/login where you might need username, email address, password, last login, etc most other contexts will only need the user id and whatever related_record_id associations are relevant.

At the same time though, see the over-engineering post I just made. Don’t hesitate to use a simple dumping ground until the smaller subsets become clear. It’s not going to hurt anything. 90% of refactoring in Elixir is just moving things around.

1 Like

Many thanks, that helped me a lot. So can one say that creating a different user schema (referencing to the single “real” user table) per context is the best/preferred way to go when not all data of a user is needed in a context? :grin:

I can’t comment on “best” but I can say that’s what I would do.

I tend to look at application design from the database out in a very normalized fashion. At the application level, just think of contexts the same way you’d be thinking of writing a SELECT statement if you were specifying only what you needed. It seems less important with the smaller columns, but leaving out giant blobs of text from an object mapping when you don’t need them is healthy for your application.

I personally wouldn’t start putting things in separate context-specific tables unless the database design itself called for it or unless I was performance tuning for some reason (lots of indexes on a single table so we needed to isolate them, for example).

That’s just me though. I’m very much a “database first” style developer. Some people design interfaces and screens first. I design my database first.

3 Likes

Me too… :thumbsup:

3 Likes

You might be interested in task-based ui’s. There is more than the CRUD ui, with relational db’s.

Modern applications typically have task-based user interfaces. A properly designed, 
task-driven user interface guides a user through a process, resulting
in a much better user experience.

http://www.uxmatters.com/mt/archives/2014/12/task-driven-user-interfaces.php
also: http://virtual-strategy.com/2014/11/20/utilizing-task-driven-ui-create-high-performing-and-scalable-business-software/

In order to get to a task-based UI, designers need to answer two questions:

How do the end users want to use the software?
How can the software guide the users through these processes?

A bit of my own fascination (I assume the article in the link has been read already, otherwise the following
text might not make sense at all):

BPM brings the task-based UI to a higher level by adding
1. User roles to a task
2. Expiration moments
3. Decisions / ruletasks, servicetasks, realtime events 
4. Low code executable modelling
5. Dashboards for performance management 
1 Like

Ok, “CQRS! DDD!” (Those buzzwords must ring a couple of bells)

One of the largest problems seen in “A Stereotypical Architecture” was
that the intent of the user was lost. Because the client interacted by posting 
data-centric DTOs back and forth with the Application Server, the domain was 
unable to have any verbs in it. The domain had become a glorified abstraction
of the data model. [..]
Many examples of such applications can be cited. Users have “work flow”
information documented for them. Go to screen xyz edit foo to bar, then go
to this other screen and edit xyz to abc. For many types of systems this type 
of workflow is fine. These systems are also generally low value in terms of 
the business. In an area that is sufficiently complex and high enough ROI 
in order to use Domain Driven Design these types of workflows become unwieldy.
1 Like

You should remember that the same newbie can choose between Rails which doesn’t require him to learn all those concepts.
Now I ask you as a newbie which framework you would choose.
This is the main issue I get about this whole thread. Most of the ppl adopting Elixir are experienced developers so framework accessibility is not one of the main issues they encounter, learning contexts is easy when you are already familiar with programming but for a newbie those concepts are hard.
Phoenix should be accessible to anyone as easy as possible, yes contexts should be part of the best practices of the framework but they should only be a “best-practice” idea and not the main focus of the framework.
I’m writing this as a newbie developer that has 2 years experience with ruby (not Rails) and 5 years with perl and can see all the beauty in Elixir and I can’t wait to do the move(well I call myself a scripted)
Another thing that bugged me was that a lot of ppl here are missing that most developers never see the business part of their web app and only see their side of the problem so how can you really expect them to see most of the benefits of adding contexts.

Ps - I’m writing this after having only 2 days of experience with Elixir and 2 hours with ecto but never even looked at Phoenix - I think you need an opinion of an outsider because you totally miss that side.
Ps2 - I do understand that contexts are the right concept and should be encouraged but not at the price of accessibility - I am totally going to use it when I would write my rest server for my new project(if it will ever be built)
PS3 - sorry I choose this specific post to reply to but the concept is the same to 90% of what is written here I fell on you as I finally got the true feel of what I should write.

One of my main goals since I got involved in Elixir was to help make the ecosystem as accessible as possible for newcomers, since that is what will ultimately make the language successful – Getting folks in the door and keeping them around passed the FP frustration gap. I’m also aware that many folks are coming into to Elixir thru Phoenix, so trust me when I say accessibility is on my mind.

Contexts are not the main focus on the framework by any means. They are only used with our generators and solely about learning tools for folks getting started. There is no Phoenix.Context.

Welcome! We place huge values on the opinion of folks getting started, so your input is appreciated. That said, please realize you just stated you haven’t looked at Phoenix yet, but you are taking a negative stance on contexts without being familiar with the framework or the generators. What would be very valuable for us is if you provide feedback around using the context generators as you’re learning Phoenix. As it stands now, you’ve taken a negative stance without even evaluating things :slight_smile:

4 Likes

I don’t think “newbies” would have a problem here. I think the people you may struggle is people who are used to other web application framework such as Rails, Django or similar. Because they are used to another way of thinking.

The problem I have with “Context” is the word. It is made into some big concept that you must learn and that scares people away.

In elixir you have modules and function. Some functions have to be made public. These are your API. Ideally you want your API surface to be as small and to the point as possible. You also don’t want to leak any implementation details out from your API.

By implementing too much in your web layer (controllers) you don’t have a clean API surface and you bleed implementation detail (underlying database concepts for exampel).

Note though, it is hard to come up with the right abstractions. And this is not something you should start implementing straight away. As someone else said it is OK to start with one context and work from there. Only after you “know” your application you are able to make the right abstractions.

The one thing I do know is that separating the presentation layer (phoenix) from your application will pay off.

WIthout proper modularisation and API design (which is what context is about) it is like developing javascript without any modules and just like loose functions on the window object. It works for a while and as long as your application is small but will give you nothing but hurt later on.

I original looked at phoenix some years ago and the apparent lack of contexts (i.e their generators produced bad practice code) and some of the lacking features in ecto was holding me off it.

But I see the phoenix team moving in the right direction all the time and they are not afraid of admitting they are wrong and can change. The idea of contexts is right but perhaps the communication of it has not been the best (if you look at some of the confusion it causes).

5 Likes

That is my only issue with it too. I’ve never seen Context used in this context before, but rather just normal separation of concerns whether via namespaces in C++, modules and submodules in ML languages, modules in Python, etc… etc… It seems to be a very common pattern that should just always be naturally done, so to this day I’m still confused why it has the special name of Context, or why it is really talked about at all when it should just already be done and used as it is as is normal programming and keeping a Separation of Concerns. ^.^;

But yeah, Phoenix’s generators were a bit noisy and put way too much in the controllers, I stopped using them very quickly and not touched them since. It is good that they do that separation of concerns, but I still do not think it should be called a context, even the word Concern would make more sense but I do not like it either… :-/

10 Likes