1EdTech / openbadges-discussion

A no-code repository for having discussions related to the general technical issues of openbadges.
10 stars 3 forks source link

Issuer badge listing/index #1

Closed brianloveswords closed 7 years ago

brianloveswords commented 10 years ago

What

A method for an issuer to advertise all of the badge classes they offer.

Why

With what we have now, it's really hard to build a service that exposes all of the learning/badging opportunities that exist. @thisandagain built something awesome during MozFest that crawls our backpack surfaces all the badge classes we know about, but this only works for badges that have already been earned, and it can't take into account a world of federated backpacks.

If we specify a way for issuers to advertise all of their badges, we (and others!) can then build tools that exposes that data in interesting ways. I also believe this helps us get a little closer to figuring out badge pathways.

How

Still thinking about this part. Based on some conversations with @thisandagain, @andrewhayward and @toolness here's what I'm thinking

Advertising the badge index

At the index of the issuer's origin (potentially on other pages as well, e.g. criteria page) there should be a <meta> or <link> tag with some pointer (HREF) to a file that has the index of all badges.

I am still researching to see whether <meta> or <link> would be better. Any comments on that would be appreciated.

Badge Index format

This part could get controversial.

JSON

Straightfoward, the file could provide an array of badge classes in JSON format:

{
  "issuer": {
    "name": "An Example Badge Issuer",
    "image": "https://example.org/logo.png",
    "url": "https://example.org",
    "email": "admin@example.org",
  },
  "badges": [
    {
      "name": "Awesome Robotics Badge",
      "description": "For doing awesome things with robots",
      "image": "https://example.org/robotics-badge.png",
      "criteria": "https://example.org/robotics-badge.html",
      "tags": ["robots", "awesome"],
      "issuer": "https://example.org/organization.json",
    },
    {
      "name": "Rad Pizza Badge",
      "description": "For making amazing pizza",
      "image": "https://example.org/pizza-badge.png",
      "criteria": "https://example.org/pizza-badge.html",
      "tags": ["pizza", "cooking"],
      "issuer": "https://example.org/organization.json",
    }
  ]
}

RSS/Atom feed

I've also been toying with the idea of providing the badge listing as an RSS/Atom feed. I'm not super experienced with that and I don't if there would be any strong benefits. I'm gonna try to get some RSS experts to contribute to this discussion.

One drawback I can see is that it would potentially increase issuer burden – it's pretty easy to generate the JSON feed, but an RSS feed would take more time and effort, potentially even requiring pulling in additional dependencies. It would also require additional dependencies on the consumer side as well to parse.

I really like being able to use existing standards where they make sense, though, and there are likely some positives that I don't know about.

thisandagain commented 10 years ago

Awesome! I'm also really not sure about <meta> vs <link>, though embedding links to JSON blobs in meta tags just feels a little weird. :smile:

In terms of RSS/Atom I think that is pretty interesting. While JSON is way easier for us nerds, because of the depth of tools available for creating RSS feeds, there might be a strong argument for it in user land.


As an aside, would now be a good time to think about extending the badge schema? Two items that arose during my experiment were those of geolocation and language specification. For example:

{
    "name": "MOOC GdP : fondamentaux des projets",
    "description": "A démontré sa connaissance du cours “fondamentaux de la gestion de projet” du MOOC GdP. Voir gestiondeprojet.pm ou http://goo.gl/Hu3GA",
    "image": "https://badge.unow.fr/badges/badge_classique_S1.png",
    "criteria": "https://badge.unow.fr/badges/criteria/22/1b605d6937b8e527cff67d9eb0bd649d",
    "issuer": "https://badge.unow.fr/api/v1/organizations/1-unow-mooc-badges.json",
    "alignment": [],
    "tags": []
}

In this instance it would be great to append something like:

{
    "language": "fr-fr",
    "location": [someLat, someLong]
}

This would allow us to easily localize search, and also provide better recommendations for pathways based on user language and locale preferences.

brianloveswords commented 10 years ago

Oh yeah, localization is a whole other issue (which I should probably make an issue for!) There are cases where people would want to have the same badge localized into different languages (and still have it be the same badge). @christi3k is also very interested in localization, so we should get her into that conversation!

toolness commented 10 years ago

This is a great conversation and I'll pitch in some thoughts soon--for now I just wanted to mention, for historical preservation, that I wrote a barebones badge indexing API draft earlier this year after some discussions with brianloveswords.

barnabywalters commented 10 years ago

The <link> element, with a suitable rel value, would be more suitable than <meta> for linking to a JSON document — see the HTML living spec:

The meta element represents various kinds of metadata that cannot be expressed using the title, base, link, style, and script elements.

vs

The link element allows authors to link their document to other resources.

Links can also be represented in HTTP headers, which can be handy — requiring only a HEAD request for discovery.

brianloveswords commented 10 years ago

Thanks @barnabywalters, that's great information. I also didn't know Links could be represented in HTTP headers! Can you link me to the location you pulled those quotes from?

EDIT:

Nevermind, I think I found it – http://www.w3.org/html/wg/drafts/html/CR/document-metadata.html

And for information about the Link header – http://www.w3.org/wiki/LinkHeader

brianloveswords commented 10 years ago

Okay, this is very useful: one of the things I was getting caught up on with <link> was figuring out the correct rel to use from the list, but apparently we can easily register our own.

andrewhayward commented 10 years ago

Finally! I've been waiting all summer to have this conversation :)

I think it would be prudent to at least consider an option that reduces content duplication. Given that publishing a 'Badge Class' JSON blob is required to create a valid assertion, it might be as well to allow for that to be the canonical source of information for any given badge.

To that end, I've considered something along the following lines:

{
  "badgelist": [
    {
      "location": "http://www.example.com/badge-class-1.json",
        "priority": 0.5
      },
    {
      "location": "http://www.example.com/badge-class-2.json",
        "priority": 0.2
      }
  ]
}

Or, for the slightly more perverse amongst us:

<?xml version="1.0" encoding="UTF-8"?>
<badgelist xmlns="http://openbadges.org/schemas/1.0">
  <badge>
    <location>http://www.example.com/badges/class-1.json</location>
    <priority>0.5</priority>
  </badge>
  <badge>
    <location>http://www.example.com/badges/class-2.json</location>
    <priority>0.2</priority>
  </badge>
</badgelist>

I've posted schemas for them here (JSON) and here (XML), but briefly, there's a location property pointing at the badge class JSON blob, and a priority property, which is a number between 0 and 1 and relative to the issuer's other badges. (I don't remember the specifics of the conversation that led to priority existing, so feel free to ignore it if you want, but it did happen!)

It might be going overboard a little at this point, but there's also a possibility that a larger organisation (think universities, for example) might want to delegate the creation of these badge lists to subgroups (departments, etc), so I also considered the option of a 'badge index' file, which could point at badge lists and other badge indexes…

{
  "badgeindex": [
    {"location": "http://www.example.com/subgroup-1/badges/list.json"},
    {"location": "http://www.example.com/subgroup-2/badges/list.json"}
  ]
}

And again, for those otherwise inclined:

<?xml version="1.0" encoding="UTF-8"?>
<badgeindex xmlns="http://openbadges.org/schemas/1.0">
  <badges>
    <location>http://www.example.com/subgroup-1/badges/list.xml</location>
  </badges>
  <badges>
    <location>http://www.example.com/subgroup-2/badges/list.xml</location>
  </badges>
</badgelist>

(Schemas here (JSON) and here (XML).)

Finally, these could be put inside a normal robots.txt file, and be ignored by the vast number of crawlers and bots out there (with the potential for them to start noticing and wondering what it is!). For example, if Google were to offer badges:

User-agent: *
Disallow: /search
Disallow: /sdch
Disallow: /groups
Disallow: /images
Disallow: /catalogs
Sitemap: http://www.google.com/hostednews/sitemap_index.xml
Sitemap: http://www.google.com/sitemap_hreflang.xml
Badges: http://www.google.com/badges/badge_index.xml
Badges: http://www.google.com/badges/badge_index.json

It's a bit more work on the crawler's part, but not an enormous amount, and reduces the possibility of badge information being wrong or out of date. Of course, these files can also be pointed at via <link> elements in a page's <head> block (as discussed):

<link rel="badgeindex" href="/badges/index.json">
<link rel="badgeindex" href="/badges/index.xml">
<link rel="badgelist" href="/badges/list.json">
<link rel="badgelist" href="/badges/list.xml">

Or as HTTP headers (as pointed out since I started writing this!):

Link: http://www.example.com/badges/index.json; rel="badgeindex"
Link: http://www.example.com/badges/index.xml; rel="badgeindex"
Link: http://www.example.com/badges/list.json; rel="badgelist"
Link: http://www.example.com/badges/list.xml; rel="badgelist"

All of this may or may not have to comply with same-origin policies in the same way that other indexes do (sitemaps, etc), to prevent link injection and that sort of thing.

brianloveswords commented 10 years ago

(Note: Updated your comment to use code fences for syntax highlighting)

I think it would be prudent to at least consider an option that reduces content duplication. Given that publishing a 'Badge Class' JSON blob is required to create a valid assertion, it might be as well to allow for that to be the canonical source of information for any given badge.

I thought about that but was worried about the consumer having to do potentially hundreds of extra HTTP requests to get usable page. I'll have to think about it some more, though.

I also don't remember the purpose of priority, though I vaguely remember having the conversation.

The more I think about it, the more throwing something into robots.txt seems like a good idea. So I'm +1 on that barring any strong objections.

barnabywalters commented 10 years ago

Oops, sorry I left out the link — it’s from http://developers.whatwg.org/semantics.html#the-meta-element and http://developers.whatwg.org/semantics.html#the-link-element, which may or may not be more up to date than the W3C version, but certainly have nicer URLs :)

Also (take this with a pinch of salt as I’m not overly familiar with your requirements) have you considered just using HTML+microformats2? I’m assuming most badge providers are going to have a human-readable HTML listing of the badges they provide somewhere already, so you could spare them the effort of publishing extra, DRY-violating, non-human-readable files as well.

thisandagain commented 10 years ago

@andrewhayward Absolutely agree re: treating the badge class JSON blob as a canonical source. The problem is that badge classes do not have globally unique IDs. Thus, de-duplicating them from any sort of index would require a deep equal evaluation which becomes incredibly expensive (and potentially complex) as the index grows. To @brianloveswords 's point, while this will necessitate many HTTP requests to build a complete index, this incremental performance hit happens in linear time and should be easy to scale using conventional means.

TL;DR - I feel having a canonical source for badge classes is an imperative for constructing the index.

thisandagain commented 10 years ago

Re: Priority. Seems like a bit of a premature optimization, although many worker queue systems (ie: Beanstalkd, SQS) would be able to use it off the shelf which would be pretty cool. The bummer is that those systems handle priority globally and it would likely take some effort to get priority to be meaningful at an issuer level. Otherwise, any issuer that set a priority of less than 1.0 would be penalizing themselves.

Re: Array of badge URIs. Ohhhhh yeah!!! :wink:

toolness commented 10 years ago

The priority field was inspired by the same field in the Sitemaps Specification, where it allows a website to say how important a page is relative to all its other pages. This allows consumers like search engines to e.g. show only the most important pages for a site, if there's limited screen space.

I was originally thinking such a field would actually be nice to add to the BadgeClass structure, so that it could also be used by backpacks and other clients to manage the display of badges from a particular issuer: for instance, if I had 70 badges from issuer X but wanted to see a "big picture" of all the badges I've ever earned from any issuer, a smart backpack might be able to take the priority into account and only show me the 5 most significant badges I've earned from issuer X, leaving lots of room for badges from other issuers.

I think the general notion of "this number indicates how important the issuer thinks this badge is relative to all its other badges" could also be very useful for other purposes that may not have been explored yet. Currently there's very little metadata available about how one badge might relate to another, and priority is a very easy-to-understand metric that could come in handy in lots of unexpected ways.

julien51 commented 10 years ago

Whoa, there are a lot of things to read :)

Discovery: or HTTP Link headers will work great i believe. There is also RFC5785, worth looking into!

RSS/Atom would work, yes, but showing "collections of objects" is usually not the most common RSS usage, but that should work. They're mostly used to describe 'timelines'. But if you go down that route, it's probably not as complex as you imagine.

thisandagain commented 10 years ago

@toolness That makes sense... I hadn't considered priority in that context. What seems strange to me though is that it is not living within the badge but outside of it within the "badgemap". To be considered part of the badge's metadata would it not make more sense to move it inside of the badge class itself?

toolness commented 10 years ago

Yup, totally--I had originally proposed it to live in the badge class, not the map, so I'm not sure how it got put in there...

toolness commented 10 years ago

<daydreaming> As an alternative (or in addition to) the priority metric, it would be SO COOL if there was a field that indicated the percentage of all an issuer's users who have been issued the badge, so that metrics like Steam Global Achievements could be leveraged by badging tools. </daydreaming>

thisandagain commented 10 years ago

We could do that calculation as a part of the index-er. :smile: We know the issuer based on the assertion and could absolutely implement a feature to track the % of assertions per issuer per badge. I've already started to think about how to increment the badge index based on the number of assertions found by the indexer as I feel it could be a valuable piece of data when designing a ranking expression (search).

cmcavoy commented 10 years ago

I like the idea of this living in robots.txt for the 'rightness' of it, but think the <link> element is more flexible in a large organization with heavy handed controls over top-level domains. We could encourage <link> on criteria pages that point to the index that badge is included in.

No matter what way we go, we'll have to provide a sitemap-like service as part of the indexer that let's an org register an index.

I agree with @andrewhayward on the index linking to other indexes - I like the idea of linking to the badge class instead of the full object, but agree that without guid's it will get weird (makes me want to tackle guid's so this can work). Maybe a sass-like toolkit will develop that allows big orgs to maintain their increasingly messy badge indexes? THE FUTURE!

re: priority - I don't remember the original conversation, but I'm all for something like it in any sort of index list. We've already run into issues not having explicit badge order returned by OpenBadger. Speaking of which - opened a discussion ticket on OBr to talk about whether or not we want to change the OBr API /v3/badges to match this spec. It makes sense to me.

Re-reading this - I think I'm coming at the discussion from less of a indexer pov and more of a API for an issuing platform. The most useful view we've used in OpenBadger is the /v2/program/[shortname] view example from MozFest. We need things like, how to earn the badge, how to apply, where to apply, etc. Which really leads to - we need to settle on a criteria page markup spec. Time for another issue!

Lastly, +1 on locale / location in the assertion. This will be super useful and awesome. +1 on allowing the index-provider to include other information about the badge for @toolness steam achievements suggestion.

timothyfcook commented 7 years ago

Moving to the archive. https://credmos.com/ has tackled aspects of this.