Best practices in structuring larger projects

Hi all,

I’m really interested in how you guys organize your projects files/folders, especially larger ones.

On my behalf, atm I have a client and a server folder and those import folders for ui, api and db just like in the todos-example, but I definitely need some refactoring. Read a few posts using local packages a lot, but I’ve really got no clue how to transform this step by step, since there’s a lot of dependencies across my usual imports.

For large and very large projects I think the safest would be to go with micro-services and micro-frontending which basically means multiple Meteor projects

1 Like

I’m very happy with the structure of https://github.com/meteor/examples/tree/main/complex-todos-svelte

1 Like

Like that concept of modules for splitting up the project a lot. What do you think about moving the client/ui part into the module folder as well?

It seems logical at first but separating the user interface into modules is really hard. I think it’s harder than backend logic.

Besides that, there might be other developers who are responsible for different parts. Managing them in different folders may reduce the complexity. I don’t know we should discuss it :slight_smile:

Our code base is structured on the approach that I mentioned and we are still using blaze. I want to move to react or svelte. I think it will be harder to change if we merge UI into modules.

The same approach can be in the client folder too. This is our main design in client folder.

1 Like

I only use meteor for app stuff and use the basic client / server directories and an imports for my API and components. I always try to keep my node npm modules and meteor plugins to an absolute minimum.

Anything that is database work, scripts and external APIs, customer support. intrusion detection, monitoring etc I keep in completely external repositories so they are not in Meteor at all and outside of it in their own version control. This has many benefits and means they are agonistic and not attached to meteor in anyway. This mean less points of failure, especially when an update is rolled out. It also means any of my external apps can be in any language or configuration I require. Also for a super admin control panel, you really do not want that code base in your app at all. In case god forbid some exploit occurred in some package and a user was able to escalate their permissions to super admin and cause a whole shtf scenario.

So for mostly all projects you’ll require some kind of app/script segregation. Where you have meteor app for all your user land stuff and then another folder of scripts an admin can run on the cli that does all the heavy lifting, importing and direct database functionality. That can all be locked out under root only sudoer’s access and is not even in the same webroot as your app so no one can ever access it via the web server. The scripts are not live to anyone over the internet so therefore are no longer an attack vector.

For any other things like customer support, follow the same protocol of having a directory for it under a subdomain like support.my-app-domain.com and if that happens to be some old junk that still works in PHP like osticket, no problem because you just make a vhost for that subdomain and don’t have to try get it to build nicely and play ball with meteor. It’s versatile.

For large projects you must and I repeat MUST run nagios or cacti or some rrdbased tool for profiling, so you can view what’s going on each server and what bandwidth and costs are. You cannot trust the person who writes your bills with this alone. Because even if they made a honest mistake, and it was just due to a spike or some miscalculation at the switch, there is a conflict of interest here. The service provider wants to invoice you as much as possible, it’s their business. So you must have your own accounting looking at your servers and be able to alert you and nip it in the bud before an attack, or total mess up ends up costing you thousands of dollars in wasted bandwidth or electricity. It’s good to be in the know.

Having a separate monitoring server is cheap, it monitors everything and makes you know how much your bandwidth’s 95th percentile is likely to be that month. Most NoCs will allow you to access their RRD also so you can compare what is going on there with what you monitor on your internal LAN. Of course AWS and Digital Ocean etc won’t give you access to this. Which is another reason to get real rack space and build your own setup, it’s significantly cheaper, you have more transparency and can get the latest hardware direct from dell or hp on lease - and not have to share with every one else on the cloud.

1 Like

We actually have a medium-sized project going on with service-oriented / microservice architecture in mind, since it will grow over the next years.

Summary:

  • split apps by target group and their use-cases (editors, team, end-users etc.)
  • extract services, consumed by multiple apps into a single app without frontend (--bare option is a good start here)
  • have an account server handling logins across multiple apps
  • implement a sustainable data-strategy before implementing performance things like caching, redis etc.
  • extract total-generic code into packages but beware of extracting business login in packages, it may couple your services and create lots of effort in the long run
  • favour convention over configuration; use Meteor.settings to define URLS and stuff that goes beyond apps / services
  • open up your apps for plugins (open close principle) if you want them to be extendable by your users
3 Likes

Thanks all for really inspiring answers. Learning so much since I started almost a year ago self-taught parallel to my main job, and this thread really covers some very new concepts I never heard of / associated with meteor before. @jkuester regarding account server, is this also a meteor based service or some oauth / ldap / different thing?

And another question to the community (maybe a bit off topic, but at least for my project a point to be solved): is there a 2022 way of implementing multitenancy? Did some testing based on forum entries experimenting with DDP connections, but never got to the point where this got acceptable.

This has always been a bit foggy when I’ve read around, so I used a old school approach - vhosts.

I just simply run meteor on different ports then setup my nginx conf to have a vhost for each port as the upstream. You can also load balance in this way it’s really easy to do.

In your nginx.conf you can just run the following:

    upstream backend {
        server localhost:3000; #localmachine
        server another-network-could-go-here.com; #somewhere out on the net
        server 192.0.0.2:3000 backup; #another server on your LAN (best)
    }
    
    server {
        location / {
            proxy_pass http://backend; #Pass it all to the backend and let the load balancing of nginx figure it out
        }
    }
}

This will mean you can have as many apps running on one web server as you desire, and you can daisy chain multiple servers via their local LAN ip. Easy peasy. No need to pay anyone for this service.

This works for ssl/https also.

In my project, I can’t really decide which folder structure to use for organizing my imports; atm I go with this structure:

imports
      |- db (Collections + schemas)
           |- MySampleCollection
      |- api (pubs + methods)
           |- MySampleCollectionMethods
           |- MySampleCollectionPublications
      |- ui (react, with hooks spread all over the place)
           |- MySampleCollectionView (react)
           |- MyComponent (using MySampleCollectionViews etc)
           |- MyHooks (with a bunch of imports since for every Collection I need at least one)
      |- lib (tool stuff)

In my client.js I import all ui and hooks for fetching data, in server.js I load all pubs and methods. UI is constructed in a way that for each document-type I have a UI view with several variants to display a certain document. So I thought maybe it could be logical to put mongo collections to the center of everything and organize it around that:

imports
    |- MyUIComponents
    |- MyCollections
        |- MySampleCollection
             |- db
             |- schema
             |- api
             |- views
             |- hooks
        |- MyOtherSampleCollection
             |- db
             |- schema
             |- api
             |- views
             |- hooks

What do you guys think? Any design flaws that come into mind? Would quite a huge reorganization of my project, so I’d be grateful for any thoughts.

Spliting admin interface from the application is nice for security but not enough.
I used the same approach which is described by @bratelefant and than changed it with mine. I was using Laravel and my first approach was like that but it’s really hard to maintain it.