tent / tent.io

The website for Tent — the protocol for evented data storage and decentralized communication
https://tent.io
Other
794 stars 97 forks source link

Post types should be composable #108

Closed mwanji closed 12 years ago

mwanji commented 12 years ago

As apps proliferate, it is easy to imagine that many apps will want to use slightly modified versions of existing types. Post composability could allow this in a backwards-compatible way, while reducing type fragmentation.

Currently, posts only have one type, so if I want a Status with a picture or a geo-located Essay, I have to create a new type that no existing apps will understand (or even be notified of).

I suggest that each post have an array of types. Clients that are subscribed to a particular post type would receive notifications if one type in the array matches. Clients could then ignore the types they can't handle, but display the ones they do. Clients that understand all the types, and what their combination means, could have a richer display. It would also limit type fragmentation, as existing types could be more easily re-used, augmented and combined.

Perhaps both post.type and post.content could become arrays with matching orders.

Examples: ["https://tent.io/types/post/repost/v0.1.0", "https://tent.io/types/post/status/v0.1.0"] is a Repost with a Status, ie. a commented Repost

["https://tent.io/types/post/essay/v0.1.0", "https://tent.io/types/post/location/v0.1.0"] is a geo-located Essay

["https://tent.io/types/post/status/v0.1.0", "https://example.com/types/post/status/v1.2.0"] is a Status with some custom fields.

longears commented 12 years ago

What happens if two post types use the same key to mean different things? Maybe Statuses want location to be GeoJSON but Events want location to be a street address.

Posts could nest things an extra layer deep the same way profiles do:

{
    "id": "oafjiofj",
    "entity": "http://you.tent.is",
    "https://tent.io/types/post/status/v0.1.0": {
        "message": "hello world"
    },
    "https://tent.io/types/post/location/v0.1.0": {
        "location": <GeoJSON here>
    }
}

This makes it easier to bolt features together. For example, I wanted to add tags and location to all the post types. This would let me easily do that.

It also helps with the versioning of types to have them broken into small pieces.

This is a pretty giant change to the protocol, though. Maybe version 2.0?

I suspect in the meantime that in the real world we're going to start seeing extra keys like tags and location showing up in all the types.

mwanji commented 12 years ago

That's why I suggested that post.content could be an array. For example:

{
  type: ["https://tent.io/types/post/status/v0.1.0", "https://tent.io/types/post/location/v0.1.0"]
  content: [
    {
      // status content
    },
    {
      // location content
    }
  ]
}

This way, there's no confusion or name clashing, but the expected structure is preserved.

This is a pretty giant change to the protocol, though. Maybe version 2.0?

We're not even at version 1.0! I agree that it's a big change, but now is the time to do it (if people agree it's a good idea). There's only one server implementation (and only one significant host). There are only a few clients that are still under active development and could accomodate the change. It will be much more difficult to make such a change later.

The main issue is whether the tent.is team would have time to implement this. I do think it'll be a huge benefit, very quickly.

/cc @danielsiders @tent

longears commented 12 years ago

Ah, I didn't quite see that. I like the array approach because it lets you have multiple copies of the same type.

tjreo commented 12 years ago

I'm not sure yet on the right way to implement this (both suggestions so far are worthy in my opinion) but want to strongly +1 on the importance of composable types. They will go a long way toward taming the number of post types required to build any given solution.

titanous commented 12 years ago

I don't think we're ready for composable post types.

Adding fields to a post shouldn't actually cause a major version bump or any backwards-compatibility breakage. Only changing semantics, renaming, or removing a field would cause a backwards-incompatible version change.

When we have machine-readable schemas in place and have much a better picture of real-world usage of posts and types, I'll be happy to reconsider. I feel like it's premature to make this change so early in the development of the protocol.

mwanji commented 12 years ago

@titanous It makes rendering posts very hard for apps and will result in posts that don't make sense.

I'm not sure the former is true. The latter is certainly a risk. For example, TentStatus might render Status+Photo as just Status, while a photo app might render it as just Photo and an Instagram-like app might render both.

It stunts the development of rich post types. For instance, we actually do think that Reposts should have a comment field.

The proliferation of marginally different types also makes it more difficult for apps. Not only would they need new code every time a new type is published, they'd also need code to update their permissions. With composable types, it would be much easier to write code that can combine types in a generic way and fewer new types would be created.

Having multiple copies of single post type is confusing and doesn't make sense.

I hadn't thought of the possibility and I couldn't think of a usecase when @longears suggested it, but it did give me a feeling of "wow, there's a lot of power hidden in this idea".

Adding fields to a post shouldn't actually cause a major version bump or any backwards-compatibility breakage.

But how would an app know to look for these new fields? Especially with a machine-readable schema, you wouldn't expect a producer to add random fields to a standardised type. And producers might not add them in the same place. It wouldn't break backwards-compatibility, but the extra fields wouldn't get used, either.

When we have machine-readable schemas in place and have much a better picture of real-world usage of posts and types, I'll be happy to reconsider.

Fair enough. I guess post type versioning would make any transition somewhat easier.

titanous commented 12 years ago

@titanous It makes rendering posts very hard for apps and will result in posts that don't make sense.

I'm not sure the former is true. The latter is certainly a risk. For example, TentStatus might render Status+Photo as just Status, while a photo app might render it as just Photo and an Instagram-like app might render both.

The key thing to remember is that there will be thousands of legitimate post types that aren't just fragments off of a status post type. If posts types were composable, this would certainly create confusing, unrenderable posts.

Adding fields to a post shouldn't actually cause a major version bump or any backwards-compatibility breakage.

But how would an app know to look for these new fields? Especially with a machine-readable schema, you wouldn't expect a producer to add random fields to a standardised type. And producers might not add them in the same place. It wouldn't break backwards-compatibility, but the extra fields wouldn't get used, either.

Apps aren't going to use machine-readable schemas to decide how to render posts. The code will know that some fields may not be there and only render them if they are in the post. Apps that are unaware of the fields would just ignore them as you point out. This type of change would result in a patch version bump of the post and the new fields would be reflected in the schema.

mwanji commented 12 years ago

The key thing to remember is that there will be thousands of legitimate post types that aren't just fragments off of a status post type. If posts types were composable, this would certainly create confusing, unrenderable posts.

I assume no single app would handle thousands of post types and that accepted compositions would emerge in different post categories, but I see your point.

This type of change would result in a patch version bump of the post and the new fields would be reflected in the schema.

OK, so new fields will be explicitly declared. I wasn't aware, however, that clients were expected to use a semantic versioning approach to post type versions.

If an app is authorised to read Status/v0.1.0 posts, will it also be notified of Status/v0.1.1? Status/v0.2.0? Status/v1.0.0? I'm assuming breaking changes would only happen when the major version changes.