-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extending "PETE" with Reusable Components So We Can Build People-Centric Standards-Compliant Data-Driven Apps Easier/Faster/Reliably #67
Comments
This. This is a huge lesson from the work we have done over the past 2 years. Our small modules (which we barely use ourselves) attract a fair amount of attention and contributions - the highly modular approach makes a lot of sense. Having now done this on our latest two client projects, this way of working makes my heart sing ❤️ 🎶 It's better for us, better for our clients and better for the open source community. Thanks @nelsonic for the proposal diagram too, having it so clearly laid out is extremely useful! |
Thanks for writing this up @nelsonic, I'm enjoying contributing to its progress and looking forward to seeing it take shape! |
@nelsonic This is awesome. I agree wholeheartedly. ❤️ ❤️
This point especially rings true for me. Although I did a lot of work with healthlocker, when I have needed to come back to it to make improvements/fix bugs/add a new feature, I find it time consuming and honestly a little daunting. The great thing about the modular approach and components is that when we need to upgrade a component, everywhere that component is used is also updated. Having to manually find and update everywhere in an application that you have done something specific can be time consuming and error prone. I really enjoy the modular approach. There a plenty of reasons for this, the top few being that it saves time on a project if we can reuse something other developers have already built (and we can use that time on the projects rather than reinventing the wheel) and code is in smaller, more manageable chunks (and often more robust as many people have thought long and hard about the best way to implement that one thing). My favourite reason though is that I feel like the code is much more accessible. What I mean by this is that when it comes to big monolithic projects, they could have (and often do have) plenty of great functions and modules that have been built into them but it is hard to know what they will have and where to look for it. With the modular approach I feel it is much easier to find exactly what it is that you are looking for, apply it to your use case and (maybe most importantly) make suggestions for how the code could be improved/enhanced. |
Agree 👍 if we are able to split applications in multiple reusable components, the creation process will be much faster and enjoyable. For example rewriting the authentication logic for each new application is time consuming and tiring! However I'm wondering if any features can be implemented with reusable components or do we need to have a limit on the kind of projects that can be implemented with modules? There is a risk to try to adapt the reusable code to match some specific features of a project. What would be an acceptable solution, accept any PRs in the reusable modules? This might pollute the API and the modules might not be as easy to reuse. Fork the modules to make them specific enough for the application? This will break the idea of reusable component. It's difficult for me to have a precise idea on how everything will work together, but I like this macro vision on how to build our next projects. A simple example which demonstrate how to use the "PETE extended" would help us to see what are the limitations but also confirm our motivations to go in this direction. |
@SimonLab good question(s)!
The only risk I see is in defaulting to the "old habits" of building all the functionality into the "Client App" instead of being disciplined and putting the functionality in a reusable package. We can only build a simple example once the Yes, we've done things a little bit "in reverse" with our latest client project because Our first/next step is to make the docs for https://github.com/dwyl/alog super beginner friendly.
Don't get "hung up" on the details of how the more advanced features like Admin and Contact will work or look. focus on the "core" components at the "base" of the stack for now. If it's "difficult" to have an idea, simply go look at We are re-imagining the Web Application Stack from the ground-up to be distributed, fault-tolerant, real-time, offline-first, metrics-driven, GDPR-compliant and fun to use for developers and end-users. |
Thanks for this write up @nelsonic, it's really useful to see the full plan of what we're working towards. I've really been enjoying working on the various parts of this so far, and am looking forward to those we haven't got to yet. The only question I have is around how all of these modules actually fit together. Based on the above, it looks like each element in the stack depends on those below it, but my understanding was that each of these modules would be completely independent of each other; so if somebody wanted to use only the You also mentioned repurposing I just want to be sure I know exactly how independent these modules are going to be, to make sure I'm implementing them correctly as we go on. |
@Danwhy thanks for the insightful feedback and clarifying questions. 🥇 Great news that you've been enjoying diving into building the AnswersEach "core" piece should be independently tested and documented. The further up the stack the more "coupled" the pieces become to the "core". We are not going to build
In our "Client" apps there will be no such thing as a locally defined "User Schema".
This will make the framework incredibly flexible and essentially allows people to "drag-and-drop" from a list of "available fields" into a "custom fields" table, thus the "Product Owner" can construct their "App" based on reusable components (think lego bricks!) without having to write a line of code. "Custom Autoforms" will do the "heavy lifting" to render the forms, validate and store the data and
It's going to be much easier to explain the reasoning for each element in the "stack" once the need arises. But here's a basic example: ("abase-ic", see what we did there...? 😉) ExampleImagine you are building a Social Network for Pet Lovers and you need to store specific data for each member of the platform including their pet's name, species, breed and date of birth. The "base"
The
These fields might be rendered on the person's "profile page" as:
A naive way of implementing this "social network for petlovers" would be to add custom fields to the person ... e.g:
That would be a non-relational/denormalised way and would mean that the "outlier" on the network who literally owns a zoo cannot list all their pets ... As you can tell from the data we are capturing for the
Repurposing "Abase"?Yes, having a "Phoenix+" stack (name TBD) which would include "users" ( Being able to reference one package in the "Client App" We need help on defining the name for this Application Framework "Scaffolding" ... The only reason I like tl;dr
Real App Examples for Learning the Stack?My personal learning objective (see: dwyl/hq#497) in the next 6 months Culminating in a "curriculum" of "7 Apps in 7 Weeks": (from my personal notebook/journal...) that anyone can use to learn how to build using the "New Stack" from anywhere!
And You can begin to see where this is going ... 😉 |
The next element in the stack is Logging. 🪵 |
Context 🤔
We have been using the "PETE" Stack for the past 18 Months and it has been a really good experience
for end-users (people using the apps we've built), developers and product owners/clients!
We love Phoenix and Elixir and feel it's been a good choice of framework and programming language.
My/our one "regret" is not pushing for more modularity earlier on in our journey with Phoenix,
which has meant that we have "locked up" most of the useful functionality in the Apps we have built
and thus have to "re-implement" lots of "boilerplate" each time we start a new project. 😞
Example 💊
A good example of the PETE stack is Healthlocker https://github.com/healthlocker/healthlocker
The end-users like using and is much better than anything the NHS had before (for this use-case). 🥇
Everyone who worked on the project can be proud of the work that has been done. 🎉
However if you look at the
mix.exs
file, you will see that while we used several open source modules created by other people, we did not create any reusable components/packages/modules ourselves ...That's "OK" because it was not the (stated) "goal" of the project to "create reusable code",
the goal of the project was to create an App that helps people "self-manage their [mental] health" and "effectively communicate with their clinicians".
However it was an aim of the project to be Open Source so that anyone could contribute!
And while we "checked the box" of Open Source by making the project
public
on GitHub,we have not had any contributions from anyone outside of the "core" team.
This raises a separate question around what constitutes "success" in Open Source: #66 ...
Our hypothesis is that if we had created Healthlocker as a collection of reusable components which then get assembled into an App, we could have aided the "core" goal of the project because by making reusable components, each time one of those components is reused and improved, the original project receives all the improvements "for free".
By creating Healthlocker as a one "monolithic" repository (AKA "monorepo")
we were able to move fast(er) initially and deliver the App to users/stakeholders quicker ... 🐎
but now when we need to implement Auth, Permissions or Chat in a new project 🆕
we have to do it all "from scratch" ... ⏳
Analogy: Smart Phones 📱
Think about the Smart/Mobile Phone in your hand/pocket, it's made up of millions of components.
The software stack that goes into making the smartphone possible is billions of lines of code.
Each time one of the elements in the software stack (Kernel, APIs, UI Libraries, Build Tools) improves,
everyone in the ecosystem (developers, users, companies) benefits from the improvement.
If the stack of software for the smartphone was a "monorepo" it would have failed long ago;
because it would have become unmaintainable and no individual person would be able to understand it!
Lessons Learned 📚
We have all learned a lot from our work over the last few years. A few lessons
The sooner you think in "data structures" the better. see: "Make Data Structures" by Richard Feldman learn-elm#120
Everyone that has access to the internet has an email address. Android (the most popular operating system by far) requires people to use a GMail account. Email is still a good way of reaching people, even if just to loop them back into the App/service you are building.
Proposal 💡
Our mission for the rest of 2018 is to create the reusable stack we will be deploying in 2019:
If this feels like "a lot", don't be discouraged or overwhelmed, we already have a massive head start!
A lot of the work on this has already been started and in some cases shipped!
Break it down into "chunks" and start from the bottom: the Append-only Log is the core of all apps.
see: https://github.com/dwyl/phoenix-ecto-append-only-log-example (if you haven't already)
@Danwhy is already making great progress with Append-only Log: https://github.com/dwyl/alog
Both @Cleop and @RobStallion have made great contributions to https://github.com/dwyl/autoform
and we are already actively "dogfooding" elements in our client projects!
We'll build a "minimalist" analytics system "from scratch" on top of alog: https://github.com/dwyl/atm
We have done some work towards this in: https://github.com/dwyl/hits
Auth will need to be assembled from the ground up based on alog, fields and autoform.
So for now, ignore the work that had been previously done.
Once we have the "base" layer of alog, Fields, ATM, Autoform, Auth and Admin, we can build the more "feature rich" tools: Contact and Feedback.
Hopefully this will clarify the "strategic" direction we are taking when building our most recent projects in a modular way.
Name? 💭
For now, we don't have a name for the collection of modules/packages.
I'd love to call this the "Obvious Stack" because most of these things are obviously useful to most apps we have (already) built and will give us a massive head start for anything we build in future.
Considering "repurposing" https://github.com/dwyl/abase as it was the "spiritual grandfather" of this.
"aBase" was built and used used for a couple of Node.js Apps in 2016/17 but not developed further, as transitioned to Phoenix in early 2017.
It's not the best name (mea culpa), but at least it conveys the meaning of what we are building.
Feedback / Thoughts / Questions / Discussion ? 💬
As always your feedback is very much invited/requested/appreciated!
If you have ideas, thoughts, questions, concerns, please share!!
Thanks! ✨
Related to: dwyl/learn-elm#121 (Creating Elm Packages) ❤️ and dwyl/hq#497 (Learning Goals). 🎯
Required by: dwyl/feedback#96 (Feedback Widget) and dwyl/product-roadmap#7 (Metrics)
The text was updated successfully, but these errors were encountered: