Giving access to Learn.co tools through LTI
Flatiron School’s Learn.co platform has some amazing features for students as they progress through our web dev and data science curriculums. We have the in-browser IDE, instant indicators for passing/failing tests, and interactive Jupyter notebooks. Understandably, these are features attractive to many other types of curriculum. Our current challenge is how to expose them to partners within their own learning environments — how to provide a seamless experience for students taking classes outside of the Learn.co platform.
Let’s say, for example, a computer science class supported by the education tech provider 2U wanted to use our in-browser IDE. We want the student to go to their own online course and use our product without even knowing it’s powered by Learn.
First, let’s look at what a lesson on Learn looks like:
There’s lots going on here beyond the readme: we have Karma, DM’s, a profile, Search, Ask a Question, Next Lesson and tests, etc.
If we strip away all the Learn branding and extraneous elements, we’re left with this:
This is the piece, more or less, that we’ll be serving to our partners (along with the IDE in Browser, not pictured here).
This is an imaginary example of what it might look like on a partner’s page:
This kind of integration can happen ad hoc. Create an API contract, serve content in an iFrame. Make your own authorization. The downside is that if you want to provide tools to your partners, you might be doing this over and over again, creating bespoke pathways and forcing your consumers to adopt to your standards. What if those consumers also have other tool providers they want to use? Then they have to adopt various standards for each of them. It’s like needing different adapters to charge your phone in different countries.
This is the problem Learning Tools Interoperability (LTI) is solving.
LTI is a protocol for learning tools to provide access to and consume each other.
At a high level, LTI is simply a set of standards that tool providers and consumers can adhere to. This essentially lets all of us agree upon using the same plugs and outlets to connect our products.
LTI provides us with:
- A set of standard parameters mapped to various aspects of a course
- Authorization standards through Oauth
When we want to give access to a lesson, we just need our partner to ask for our product in a very specific way. That opens us up to serving many partners with one pathway. It asks them to subscribe to a standard that (hopefully) their other tool providers will also adopt.
LTI calls apps like Learn.co “Tool Providers” because they provide the actual lessons students will see. They call the partners who expose them within their learning hubs “Tool Consumers” (yay for explicit naming). When a tool consumer wants to launch one of their tool providers, they send a “Launch Request” (give these guys a medal).
A launch request is simply a post request from the tool consumer to the tool provider. It contains a few key elements:
- Data about the lesson they want to serve and the user requesting it
- A consumer key
- A shared secret
- The oauth signature method
That data includes information about the lesson type and the requester’s level of permissions. We use the last three pieces to authorize the request. Our flow looks like this:
- Receive launch request to a particular LTI endpoint
- Check that we have the consumer key stored and determine which consumer is requesting our product
- Use oauth verification (we used
simple_oauthin our Rails app) to validate the signature (this is an entire blog post unto itself)
- Set permissions for the request based on the roles sent in the post request
- Respond with a view for the requested lesson
- The lesson will be served to the requester in an iFrame within their app
Tools for Development
We relied heavily on LTI’s mock tool consumer and tool provider (Saltire) during development.
The best part is that at the outset, both parties (consumer and provider) can work independently to scaffold their pieces and be very close to a working integration when the time comes to fit them together.
One thing to note is that the version of the LTI spec we’re using also includes a field called “resource_link_id_history”, which is how we’re able to version lessons. Unfortunately, Saltire doesn’t provide this field yet, so we had to recreate the LTI post request with Postman.
With and without LTI
With LTI, Flatiron school now provides the ability for our partner to make the following requests:
- As an instructor, author a new lesson
- As an instructor, author versions of that lesson
- As an instructor, preview the lesson as a student
- As an instructor, view a specific student’s lesson
- As a student, view a lesson
Our backend team has worked completely independently of our partner’s frontend team, made possible by the LTI contract. We can expect more features and rapid development on both sides as a result.
Thanks for reading! Want to work on a mission-driven team? We’re hiring!