Hacker News new | past | comments | ask | show | jobs | submit login
Meteor and Qt (achipa.blogspot.com)
162 points by achipa on Dec 22, 2014 | hide | past | favorite | 41 comments

There is a lot opinions on HNews that Meteor is too monolithic and it's bad: https://news.ycombinator.com/item?id=8772563

However, that kind of projects show the opposite. It is in fact very modular.

The fact that so many dismissed it without giving it a serious look made me interested in seeing what it was really about. Long/short - it's an amazingly focused, fun and easy stack to work with. I think the fact that it's easy, or at least seems easy and probably because it's another javascript framework makes it an easy target to dismiss on HN. If you are coming from a web background like myself (aspx, ruby, etc) then it's quite a revelation how fast, fun and easy it is to work with.

I think that Meteor is pretty awesome, but it isn't good for a lot of use cases out of the box... If you need really granular and flexible security around your models, the out of the box security isn't (or wasn't last I checked) good enough.

Common case.. GROUP_A users can read/write their own documents, but only read other user's documents in that group... GROUP_B can read/write their own documents as well as all documents owned by users in GROUP_A. This is a pretty typical scenario for management chain permissions, but when I've looked ad Meteor and similar solutions it wasn't an option (or incredibly difficult to implement).

At a high level, what you're describing is pretty straightforward to implement. You just publish the data a user has access to read, and you use allow/deny rules to determine which they can write to.

You should take a look at the Roles package: https://github.com/alanning/meteor-roles

I recommend taking another look at Meteor's security because although it's different to other platforms, different doesn't mean inferior. It's actually very powerful and simple once you get the hang of it.

Cool... as I admitted it's been a long while since I've looked at implementations... last I looked, if you opened your Meteor server to the (html/web) client, the client could do nasty things to your backend database, or you had to implement some complicated and/or not very flexible permissions... I'm glad to see that this has changed.

This is more of a data modeling and permissions question, more dependent on the database choice rather than the framework I'd say. Since Meteor only supports Mongo right now, I'll use Mongo terms (collections & documents)

Meteor gives you an accounts collection so you don't have to declare it yourself. But we do need to declare the Groups Collection

    Groups = new Mongo.Collection('groups');
Let's assume we want Users and Groups to have a many to many relation, so each User doc has an attribute `groups`. `groups` is an array of which each element is the unique id of a Group document. Similarly, Group documents have an attribute `members`, an array of which each element is a User document unique id.

There is a third Collection needed, documents.

    Documents = new Mongo.Collection('documents');
Each document in the Documents Collection has an `owner` field that is the unique id of a Group document.

To handle the security for inserting or updating the Documents Collection, you need to set 2 allow rules on the Collection to check if the document.owner is in the user.groups array.

      insert: function(userId, doc) {
        // doc's owner must be one of logged in user's groups
        return Meteor.user().groups.indexOf(doc.owner) > -1;
      update: function(userId, doc, field, modifier) {
        return Meteor.user().groups.indexOf(doc.owner) > -1;
As for reading the document, you do that when declaring your Publications. Easiest would be to publish all of them, but you could also pass in a groupId or array of groupIds if you wanted to have some restrictions.

    Meteor.publish("documents", function() {
      return Documents.find();

I am not a hater, quite the contrary. I've messed around with Meteor just a bit, and loved it. But I cannot get my head around one thing: why in the world would anyone actually choose to use MongoDB over Postgres or MySQL ?Is there actually a use case where a NoSQL db would be as good or preferable? Or is it really all just a matter of people being intimidated by SQL? Because everything informed and trustworthy that I read on the subject says that NoSQL is simply not robust enough for doing anything more complicated than storing a list of names and email addresses for a simple user forum. That ain't gonna cut it for most apps.

My web development experience started with Rails, Postgres, and SQLite about 16 months ago and starting using Meteor about 10 months ago. In the handful of Rails apps I made, all of my interactions with the database were done through Active Record; I was an abstraction away from any SQL queries. I declared my relationships and got the data I wanted with simple `object.attribute` syntax.

In Mongo, I do the same thing but without an ORM. I declare objects and insert them. If I want relationships between collections I have to declare them myself, but that's just declaring some foreign key fields. I denormalize my data model in some places so I don't have to do that too often, though. And Meteor gives me this interface on the client as well — that along with data reactivity and a pub-sub architecture is a lot of fun to build with.

I've seen a lot of hate for Mongo and I'm not sure why. SQL and NoSQL databases are both capable of doing the same thing, they just have different use cases that they excel at. This video (https://www.youtube.com/watch?v=rRoy6I4gKWU) is the clearest talk I've seen explaining their differences, and having watched that I'm unsure of why people are so rabidly for or against each type of database.

Remember that Meteor only just reached v1.0. There still is much to come from the platform. Redis support is being implemented currently, and shows great promise: https://groups.google.com/forum/m/#!topic/meteor-core/Jl5Jt7... Several people are working to integrate standard SQL support, too: https://github.com/numtel/meteor-mysql http://www.lshift.net/blog/2013/02/25/live-updates-to-meteor...

It was a big concern at first for me, too. But the platform is so much fun to develop with I decided to start developing with it anyways. Seeing the pace at which things are developing with the platform, and knowing about these non-Mongo data store efforts, I am certain that this won't be a drawback for the platform for very long.

AFAIK The reactive part is not that easy to with Mysql et al - sure, you can hack around stored procedures, UDF and such, but it's far from being elegant. If you "think in SQL", then of course nosql seems to make everything difficult, but in reality, you're just taking back some of the logic and heavy lifting from the DB server in exchange for more freedom/scalability, which may or may not be something you want.

Thanks to all for the intelligent replies.

I 'think SQL' all day, or at least a simple subset of it, and I need to learn more. It's paying my bills as a .NET/JavaScipt dev, you know? I'd like to integrate it into my hobby projects. But I'm gonna watch that video linked above and see what it sells me. I certainly don't have any innate resistance to thinking of data as (basically) JSON arrays. I love that. We use that sorta stuff all the time at work, passing data back and forth, to and from the core client JavaScript functions.

I just can't shake the notion that NoSQL is so popular because SQL just is NOT. And I get that: SQL is freaking complicated once you get to the parts that make it so powerful. But maybe that's all a misunderstanding on my part.

How does your example prevent someone with access to your meteor server from bypassing your custom permissions? My understanding is the code in question runs on the client.

I think the code runs in both places. In the client, it describes the messages it will send, and in the server, it describes the messages to expect. So the server still verifies that the database requests are only permitted ones.

There is no difference compared to a web page - the permissions are still handled server-side, I'm just relaying the events via DDP.

Agreed. I think a lot of that is based on Meteor (understandably) pushing their entire stack. I've always been intrigued by their docs which state:

  By default all apps include the meteor-platform 
  package.   This automatically pulls in the packages that 
  make up the core Meteor stack. If you want to build your 
  own custom stack, just remove meteor-platform from your 
  app and add back in whichever of the standard packages you 
  want to keep.[0]
Granted, I've always used the full stack but I'd be interested in seeing some examples of taking a more modular approach at a lower level than adding packages on top of the core stack.

[0] http://docs.meteor.com/#/full/usingpackages

True - even for DDP there are already a number of client libraries not strictly related to Meteor front-ends, as seen from http://meteorpedia.com/read/DDP_Clients

I just wrote the Haskell DDP client last week :)

There were some concerns as to how native this is - I'm not rendering any HTML. The client side does use the JSON-style QML, but that's just the declarative UI language of Qt - your high-performance code can be C++, Java, or whatever is the native language of the platform. If you wish, though, you can write your whole app in JavaScript, too, but that's an option, not a requirement.

Hi, I'm Attila, the developer of Qondrite - the interface between Meteor and Qt in the article. If you have any questions, feel free to ask, I'm always looking for new perspectives, comments and will be happy to answer!

Really impressive work, thank you. I intend taking an in-depth look later, but just at the moment I hope you'll indulge a more-or-less off topic question; What tool did you use to create the youtube demo on your blog ?

I used a Chrome extension - Screencastify ( https://www.screencastify.com/ )

Much appreciated, thanks.

Meteor is monolithic in that it forces your app to be structured in a particular way - It dictates how you should handle your data and how your scripts get loaded/bundled into your app. That said, I think it's much more flexible (and scalable - In a business sense) than a closed solutions like Firebase. I think Meteor is suitable for most projects and monolithic isn't always a bad thing - There is some negative stigma around the term but it's not entirely fair. People don't go around calling Linux 'monolithic' even though it is!

It's definitely monolithic, but depending on what you're doing it can be a real time saver to have a lot of decisions made for you up-front.

This is really interesting. I use meteor for the web, but am frustrated with mobile html5 client clunkiness.

If i understand: - your UI is written in QML. - you are using Asteroid to turn DDP protocol messages into JS events? - are you then reactively changing the QML markup and asking QT to re-render your UI? I'm interested how this part works.

How granular is the reactive rendering, ie the whole page every update, or just changed components (like reactjs DOM diffing)?

Have you dealt with other client side things like routing and page changes, or is it currently content for QML widgets?

How far does QML allow native widgets like tab controls? Does a QML app end up just as janky as html5?

Did you look at just having a QT application that would talk DDP? I guess QML looks like json/markup so it's more appealing for porting an existing meteor app, and it's markup rather than code, but some mapping to QT would presumably give much more control?

How do you deal with client side logic? If QML is just a layout descriptor markup, if you need actual logic client side, how do you bridge between that and the meteor backend? I see Asteroid allows you to send data back and call Meteor.methods. Oh I see QML actually anticipates modules in JS: http://doc.qt.io/qt-5/qtquick-tutorials-samegame-samegame3-e... http://doc.qt.io/qt-5/qtqml-modules-topic.html

Does QML support a webview component? In which case you could also mix in some pages just as webviews if you didn't want to rewrite your whole app in QML? Then again only attractive if the QT webview component uses latest chrome renderer at an OS level, and no JS bridge was required back to your app... that would be like a turducken anti-pattern.

Overall very interesting, thanks for sharing!

Yes, I'm using Asteroid to talk DDP/JSON with the rest of the Qt app.

In the example, I'm using models (think MVC) and updating that model, which then automagically updates the UI.

I'm not (yet) pushing the QML via Meteor, but that is the next logical step. Should the UI change (say, radioboxes instead of checkboxes), the plan is to do a diff and change altered components (this should be doable as QML's format is still close enough to JSON).

QML already has a decent set of controls (http://doc.qt.io/qt-5/qtquickcontrols-index.html) but I'm working on wrapping native components so there is full coverage of ALL components (this was actually one of my previous posts http://achipa.blogspot.com/2014/11/qml-wrappers-for-native-a...)

Of course, you could write a C++ DDP lib (and on the long run, probably should, merely for the performance boost), but asteroid and JS just made a proof-of-concept that much easier to build.

QML is not just a layout descriptor - you can embed javascript in it. Think about QML as HTML written in JSON, but without the HTML implied semantics.

Still, JS could also be shuttled accross the DDP connection, and could be run or changed client-side, there is no difference between those and QML as I mentioned above, though this is also something planned-but-not-implemented-yet.

And finally - yes, QML has a webview component(http://doc-snapshot.qt-project.org/qt5-5.4/qtwebengine-qmlmo...)

Wow, QML looks... really nice. Has anyone used it to deploy cross-platform apps to iOS/Android? What was your experience? Biggest drawbacks?

As of 2012:

* Lack of documentation about QML itself (first and third party)

* Unhandled or unsupported corner case like trees that are a pain to implement using recursive rectangles

* Very limited set of widgets (this has improved)

* Ubuntu/Blackberry/Sailfish/PlasmaActive SDK are incompatible

You can hack your way around and get back a good old imperative QPainter and be done with it, but it kind of void the whole point.

In all honesty, Qt has come a long way since 2012 - QML is reasonably well documented nowadays. Controls (the widget library), while not a silver bullet, are good enough (at least on Android, haven't used iOS all that much) so normally you don't need to go as low as your own QPainter or even Rect-s.

My stack uses Appcelerator, Rails, and Meteor.

Appcelerator... kind of sucks. But it's much better than HTML5. It performs much better than HTML5, but I find it very hard to write. There's just way too much quirkiness and hacks to make it work. The only thing I like about it is that it's written in JavaScript (but it would be fun to learn a new one).

How does QT compare in this regard?

Performance-wise Qt is quite good, but still comes up a bit short on the Widget quality and consistency side - this is where project like my native component-wrappers come in to the story (shameless plug - http://achipa.blogspot.com/2014/11/qml-wrappers-for-native-a...). The good news is that you can still keep on the JSON/Javascript side for all of this, regardless of whether you use custom UIs, use Qt Quick Controls or something else.

Long story short - it's not quite an Appcelerator replacement just yet, but certainly keep an eye on it! :)

What's the difference between this and Xamarin?

This is a more full-stack approach - Qt and Xamarin are geared more towards creating standalone apps. What you get here is the reactive back-end (plus web-site for free). This setup can be used for both data and UI - you could for example publish a new UI (not just content), and all native apps would automatically be updated on the fly. If you take a look at the video - if you do this with Xamarin (or Qt) you would need to manually connect to a database or poll a RESTful service to see current data.

It's worth noting that if you wanted to create this kind of real-time app with a Xamarin frontend, you could do it quite easily with ASP.NET on the backend and SignalR.

That's certainly possible for the data part - but a lot harder for UI/code. With the method I'm using, you can actually push code AND UI to the client on the fly. As far as I know, that's a lot more difficult with Xamarin.

Also, the licensing is a lot more flexible than with Xamarin and Qt does provide support for more platforms.

It looks attractive, but at these times, the client application can be easily be auto-updated, that's how all applications work, including those made by Google.

Just wondering - what auto-update mechanisms are we talking about when it comes to native apps?

In the case of Android, jsu uload the new version to Google Play and the applicatio will auto-update it self.

This is not the same thing by a long shot - you cannot force a Google Play update, and that update will take hours or days to trickle down to the users. What we're talking about is that the application updates itself instantly, even WHILE RUNNING. The user needs to nothing, no "update your app" or "newer version available". I can literally add an option in the settings menu or change something in the app and it will immediately be reflected on ALL clients connected without touching the appstore.

If you want a higher-level cross-platform websocket layer between client and server you could also checkout WAMP (http://wamp.ws) as an alternative to DDP. You would need to implement some things on your own, but on the other hand it's more of an open standard and there are already multiple targets available.

Looks nice - Meteor natively speaks DDP so it makes most sense to use when talking to Meteor, but for other back-ends I will certainly consider WAMP! (no reason why this principle could not be applied to other back-ends hooking into the same WS powered Qt front-end)

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact