rebblestore-api icon indicating copy to clipboard operation
rebblestore-api copied to clipboard

Api-Ui Functions Proposal

Open sGerli opened this issue 9 years ago • 23 comments

Rebble Store Api UI Functions Proposal V1.2

This is a proposal for communication between Ui and Api for the Rebble Store.

UI Communication

The Api should have various functions for communicating with the Vue.js UI, I propose this ones:

  • [ ] getHome(platform, isApp) (isApp is used to identify if we are talking about the watchface home or app home) this should return this:

    {
      "slider": [
        {
          "imageURL": "http://example.com/image.png",
          "altText": "My Featured",
          "id": 75 // ID is then used to link this banner with the collection
        },
        {
          "imageURL": "http://example.com/image.png",
          "altText": "My Featured",
          "slideId": 75 // ID is then used to link this banner with the collection
        }
      ],
      "appCollections": [
        {
          "headerTitle": "Fresh Picks",
          "id": 76576, // Again used to link with the app collection
          "cards": [ // Should only return 8 cards
            {
              "title": "My App",
              "isApp": true, // This is to decide screenshot/icon size
              "imageUrl": "http://example.com/image.png",
         	  "thumbsUp": 24,
              "id": 32 // To link with the app-detail page, this id is unique for each app
            },
            {
              "title": "My App",
              "isApp": true, // This is to decide screenshot/icon size
              "imageUrl": "http://example.com/image.png",
         	  "thumbsUp": 24,
              "id": 32
            }
          ]
        },
        {
          "headerTitle": "All Apps", // This should always come but it should be the last item
          "id": 765346,
          "cards": [ // Should only return 8 cards
            {
              "title": "My App",
              "isApp": true, // This is to decide screenshot/icon size
              "imageUrl": "http://example.com/image.png",
         	  "thumbsUp": 24,
              "id": 32
            },
            {
              "title": "My App",
              "isApp": true, // This is to decide screenshot/icon size
              "imageUrl": "http://example.com/image.png",
         	  "thumbsUp": 24,
              "id": 32
            }
          ]
        }
      ]
    }
    

  • [x] getCollection(id, platform, page, popular) (popular is a boolean it only is valid in tags (categories), in any other case it should be ignored used to change order from Popular to New Releases) this should return:

    {
      "cards" :[ // Each page should not contain more than 12 cards
      	{
         "title": "My App",
         "isApp": true, // This is to decide screenshot/icon size
         "imageUrl": "http://example.com/image.png",
         "thumbsUp": 24,
         "id": 32
       },
       {
         "title": "My App",
         "isApp": true, // This is to decide screenshot/icon size
         "imageUrl": "http://example.com/image.png",
         "thumbsUp": 24,
         "id": 32
      }
     ]
    }
    
  • [x] getTags(n, platform) (n is the number of tags to get (most popular first)) should return:

    {
      "tags": [
        {
          "title": "Games",
          "id": 324 //App Collection ID
        },
        {
          "title": "Daily",
          "id": 324 //App Collection ID
        }
      ]
    }
    

  • [x] getApp(id, platform) (if platform is blank it will be ignored and basalt will be selected by default) it should return:

{
  "title": "Smarty Weather",
  "assets": {
  "screeenshots": [
    	{
      		"imageUrl": "http://example.com/image.png"
    	},
    	{
      		"imageUrl": "http://example.com/image2.png"
    	}
  	],
    "appBanner": "http://example.com/banner.png",
    "appIcon": "http://example.com/icon.png" // Only if it's an app
  },
  "description": "My large description",
  "author" {
  	"name": "Stefano Gerli"
    "id": 65
  }
  "appInfo": {
    "pbwUrl": "http://example.com/app.pbw"
    "rebbleReady": true, // True if the developer has authorized us to distribute his app
    "updated": "Dec 7 2016",
    "version": "4.4",
    "tags": [
    	{
      		"title": "Games",
      		"id": 324 //App Collection ID
    	},
    	{
      		"title": "Daily",
      		"id": 324 //App Collection ID
    	}
  	],
    "supportUrl": "http://support.example.com",
    "authorUrl": "http://example.com"
  }
}
  • [x] getAppVersions(id) this should return:

    {
      "versions": [
        {
          "number": "4.4",
          "releaseDate": "Dec 7, 2016",
          "description": "My changelog 7"
        },
        {
          "number": "4.3",
          "releaseDate": "Dec 4, 2016",
          "description": "My changelog 1"
        }
      ]
    }
    

  • [x] getSearchResults(searchQuery, platform) this should return:

    {
      "successful": true, // false when no result was found
      "cards" :[ // Each page should not contain more than 12 cards
      	{
         "title": "My App",
         "isApp": true, // This is to decide screenshot/icon size
         "imageUrl": "http://example.com/image.png",
         "thumbsUp": 24,
         "id": 32
       },
       {
         "title": "My App",
         "isApp": true, // This is to decide screenshot/icon size
         "imageUrl": "http://example.com/image.png",
         "thumbsUp": 24,
         "id": 32
      }
     ]
    }
    
  • Collections (card collection, this name comes from the Vue UI) are groups of apps (Featured, fresh picks, and tags)

  • Tags are our replacement to app categories they have an id that is also a reference to a collection).

  • There are only 3 types of id:

  1. App Collection (for features, tags, banner slides)
  2. App Id
  3. Author Id
  • Platform should be: aplite, basalt, chalk, or diorite.

  • I'm still missing the thumbs up add on and remove one and also a way to fetch them for the app details page.

  • I want to hear what do you think and what can we change to make it better.

sGerli avatar Dec 31 '16 18:12 sGerli

I mostly agree.

Why don't we specify the platform on getCollection, getTags and getSearchResults though?

aveao avatar Dec 31 '16 20:12 aveao

@ardaozkal that's a good idea, I updated it.

sGerli avatar Dec 31 '16 23:12 sGerli

I suppose I'm a bit lost as to what exactly the difference between a tag, a collection, and a category are. Might be that I am just new here (which I am), but I haven't seen a comprehensive breakdown of the data structures we intend to utilize. (Please point me at it if I am wrong here) With multiple teams working against this dataset, a formal specification is REALLY necessary so we don't miscommunicate about what we're doing and what primitives we all have access to.

A formal API document would also really help all involved, methinks. This is a good start towards that, but I think there should probably be more.

bbenne10 avatar Jan 02 '17 22:01 bbenne10

Updated with @bbenne10 ideas.

sGerli avatar Jan 02 '17 22:01 sGerli

So, if I am reading this right - a collection and a tag are the same thing? This doesn't feel right to me, as they seem to be treated differently in one direction than the other. For instance, the "Fresh Picks" collection should likely not allow a user to apply it to their upload, which will require special casing a set of collections (this can be done, but will be cumbersome no matter how it is implemented).

My vision had been that a "Collection" is a set of applications as decided by the administrators (or some algorithim on the administrators behalf) - such as "Fresh Picks" or "Popular" or something similar. These could be generated by a cron job or something to update the database without intervention.

Tags are user supplied strings of text that may be queried (much like collections), but which are only subjected to a smell test for inclusion (no profanity, utf-8 text only, n characters at most, no spaces or something).

Certainly there would be some overlap between the two, but it makes sense to me to have both. The websites I am basing this on are PixelFuckers (which is no longer around) and customize.org (which is now awful, but was decent before the mods left and the domain changed hands). The categories are heavily moderated by the administration team and can be changed either by hand or by a cron job, but the tags are how the community categorizes their own content. I'm not formally requesting this, but I do think we should give some more deep thought to this before we implement the entire thing :P

bbenne10 avatar Jan 02 '17 22:01 bbenne10

I always thought like

tag is for example "star wars", which includes all star wars apps and faces etc

collection is for example "new year watch faces collection", displayed on main page etc, usually hand picked

category is for example "games", includes all games

aveao avatar Jan 02 '17 22:01 aveao

@ardaozkal: that's pretty much inline with what I mention in my comment above, but doesn't completely match what @sGerli's (edited) original post indicates. The text "Tags are our replacement to app categories they have an id that is also a reference to a collection)." indicates to me that categories are no more and will be entirely replaced with tags.

bbenne10 avatar Jan 02 '17 22:01 bbenne10

Tags and collections aren't the same things but each tag has an app collection. In this case collections are just any group of apps, even apps developed by an author. Collections aren't editable, they are automatically written. The only collections that can be edited by admins are the ones that have been created manully, like "Fresh Picks". Each collection has an id. For example I have a tag and that tag says that it's collection is id = 5 so I ask for collection 5 to the backend. And for featured collections we could have in the DB a table called featured and it has titles and ids so when I ask for all of featured elements the backend uses that id to search for the right app collection in the collection table. And in the collection table theres just collection id containing an array of app ids. And for tags because they have 2 different orders (New Releases and Popular) they should reference 2 different collection ids.

Tags will be added by moderators and each app can have more than 1 tag. Edit: sorry if I confused you even more

sGerli avatar Jan 02 '17 22:01 sGerli

Aha, thanks for clarification @sGerli, your approach makes more sense now. 👍

aveao avatar Jan 02 '17 22:01 aveao

@sGerli: So is this what you're looking at? (Please ignore the rest of the board - it's my home office :P) If not, I am still misunderstanding something

bbenne10 avatar Jan 02 '17 23:01 bbenne10

Yes

sGerli avatar Jan 02 '17 23:01 sGerli

okay. Is this expected by Vue or something? This feels over normalized to me (Why can't category and tag simply hold their own references to Application?) I might remove the "collection" idea entirely were I designing this (which I suppose I now am, if I'm being honest with myself ;) ) I don't see the advantage of another table to go through. Am I missing one?

I just thought of this: what if we have a type flag on the Collection table that denotes either a Tag or Category. This allows us to flatten the db schema by a level, which will be nice on my end.

bbenne10 avatar Jan 02 '17 23:01 bbenne10

Nope, If you think we could make a change just copy my proposal and edit it.

sGerli avatar Jan 02 '17 23:01 sGerli

We still have to discuss the database structure.

sGerli avatar Jan 02 '17 23:01 sGerli

That's exactly what we're talking about right now, but you might not be seeing it that way. The API endpoints you're asking for are going to (in my implementation right now) be just a slight abstraction on the tables. My implementation features this idea that each "type" of resource should be referenced in a consistent manner when queried over the api so I have inplemented a to_json method for each table that serializes it's data to JSON. So far I only have the Application table, but I intend to take this discussion and map those tables in the coming days.

I'm not sure if @frostyfrog has an opinion on what I'm saying above and it might be different for this repo, but I have a strong opinion that an API should only be a light abstraction on top of a database schema (it allows less to go wrong, and we've proven time and time again that that's a good thing)

bbenne10 avatar Jan 02 '17 23:01 bbenne10

Ok, but if you want to make any change or modification just copy and edit my first post.

sGerli avatar Jan 02 '17 23:01 sGerli

Okay. So I'm working through this by implementing it in my own repo (which I might push to a 'python-impl' branch or something just so it's tracked in this repository)

So far I have this: Applications belong to Collections. These Collections have a type field that holds a string that indicates what type of Collection the record represents. I didn't want to make this another table, since we can enforce the insertion of the proper types without an additonal join on a reference table by just controlling our DB inputs well. (SQLAlchemy helps here too, as it has a "ChoiceType" table that enforces things like this easily).

Currently, we only have two types: Category and Tag. I haven't yet started it, but I intend to begin implementation of the aformentioned endpoints in terms of this Collection table. I'll have my (current) code pushed (somewhere...either my repo or a reference branch here) by the end of today. I hope to get the reference implementation of the endpoints started, but it may not get completed today.

bbenne10 avatar Jan 08 '17 15:01 bbenne10

This is mostly done, I think we are just missing getHome() which should work for apps and watchfaces.

sGerli avatar Jan 29 '18 01:01 sGerli

Yes, waiting for the auth system to be done, because ideally it would be an administrator account with a dashboard who would be able to choose what the featured apps are and whatnot

azertyfun avatar Jan 29 '18 11:01 azertyfun

Yeah, the admin should be able to manage collections like Fresh Picks and assign those to the frontpage. He should also be able to manage slider images and links.

sGerli avatar Jan 29 '18 14:01 sGerli

I just realized something else, we need that getCollections and getAuthor return an app icon if it's a watchapp. That way users don't get confused about wats an app and what's a face.

sGerli avatar Jan 29 '18 19:01 sGerli

getAuthor also kind of needs to be on par with getCollections, with page numbers, and maybe platform.

sGerli avatar Feb 02 '18 01:02 sGerli