Bonfire is a large project I am currently working on in my spare time. It is a site I am creating for Boy Scout troops to easily administer their troops. In this devlog, I’ll explore how I decided to structure my application.
Project structure
First off, I am keeping everything in a folder called Bonfire
in my /home/Dev/
directory. I am currently keeping both frontend and backend in the same folder and git repository. I realize that I should probably split them up into separate git repos but that will come down the line.
I created a folder called frontend
and backend
to split up the main logic. So far my file structure is as follows:
- Bonfire
- frontend
- backend
- README.md (README for Git)
- .git (Git stuff)
- .gitignore (Git stuff)
Structuring the backend
As am I using Flask for my python backend, I basically have the freedom and flexibility to structure the folders however I want. But I would like to keep it standardized. Flask-RESTful and Flask both provide a project-structure guide which I have incorporated into my structure.
Here’s how I am structuring my Python-Flask backend
- backend
- models
- __init__.py
- user.py
- event.py
- resources
- __init__.py
- user_endpoints.py
- event_endpoints.py
- db.py
- secrets.py
- views.py
- run.py
- requirements.txt (Pip package info)
- venv (Virtualenv stuff)
- __pycache__ (Python cache)
- models
The models
folder contains all the models for the MongoDB database. This includes users, events, etc. You can see that I currently have a user.py
and event.py
to hold the model schemas.
The resources
folder contains all the REST endpoints. Initially I kept all of them in a file called resources.py
however it got a little too unwieldly. So I separated my Flask-RESTful endpoints into separate files to make them more manageable.
db.py
is just a little file that contains some boilerplate code to connect to the database. secrets.py
contains all the passwords and secret keys. The keys are not actually stored in the file. secrets.py
handles the retrieval of the keys from environmental variables so no actual passwords are stored. views.py
holds a minimal amount of flask views (as I am not using Jinja rendering). run.py
is the main Flask runner.
requirements.txt
is used to keep track of pip installed packages. This is generated by running a pip freeze > requirements.txt
. Then if you are moving your project onto a new machine, you can simply run pip install -r requirements.txt
and immediately have all your packages running. venv
is generated by the virtual environment so the project pip packages don’t interfere with system installed pip packages. This is a must for any python project.
Structuring the frontend
The frontend is basically just a standard node.js directory structure created by vue-cli
- frontend
- build (Webpack generated)
- config (Webpack generated)
- dist (Webpack generated)
- src
- assets
- logo.jpg
- header.jpg
- components
- dashboard
- widget1.vue
- widget2.vue
- event_page
- events
- Dashboard.vue
- EventPage.vue
- Events.vue
- Home.vue
- NotFound.vue
- dashboard
- router
- index.js
- store
- index.js
- main.js
- App.vue
- assets
- static (Webpack generated)
- node_modules (Node.js generated)
- .babelrc (Webpack generated)
- .editorconfig (Webpack generated)
- package.json (Node.js generated)
- .gitignore (Git generated)
- .postcssrc.js (Webpack generated)
There’s a lot in here but most of it is just Webpack and Node.js generated config file junk that we can ignore for now. The important stuff is in the /frontend/src/
folder. Assets like logos and images are kept in the assets
folder. Vue router and Vuex store are kept in their own folders.
All the Vue components are split up into their own single file vue components. For example Dashboard.vue
, Events.vue
, etc. These are all their own pages in the SPA. Then to batch them even further, each SPA page gets it’s own folder with the Vue component widgets it uses. You can see that dashboard has 2 widgets that is embedded on the page. This makes it very helpful in compartmentalizing application logic. Making changes to the widget does not alter the rest of the code.
Conclusion
And that’s how I decided to structure Bonfire. It may undergo changes in the future. If you have any suggestions please tweet me!