speakT
, locateT
, drawT
, doDogmaT
, findWayToRescueTheDolphinsT
.TEW is built around the not-rare case of delivering all the data a client application needs in one big gulp. We don't plan to make huge apps. We plan to make micro apps that deal with one chunk of data at a time, and where each app operates on only the resources which "belong" to it.
TEW is proposing a software design pattern modelled on the letters of our way.
Thing
. You will...Thing
s of different types against the engaged Thing
. You can...Thing
you list. Feel free to...A key aspect of our pattern will be the use of the Schema type https://schema.org/ItemList in every thing.
We have to update the example of the smallest possible thing:
{
"identifier": "1",
"ItemList": {
"itemListElement": [],
"itemListOrder": "",
"numberOfItems": 0
},
}
With TEW you could have ten favourite apps in your "10FavouriteApps" App and I could have five favourite apps in my "5FavouriteApps" App where one of my five apps is your "10FavouriteApps" App.
There will be no need to fetch related records, or even be concerned with any relationships outside the data package. itemListElement
will hold a single list of all the related records, and because they will be of different Schema types, they will be easier to operate on.
In TEW, even though the data structure could be interpreted and processed many_to many, our client apps will only deal with a single one to many relationship.
TEW will have twelve endpoints to manage all the normal CRUD data operations. CRUD was a useful acronum, but it never covered all the operations. TEW is extending CRUD with some new acronyms:
Usage: <turdT> <identifier>
Each takes one required/positional parameter for identifier
. Optional parameters for all other properties.
takeupT
As in "take up carpentry". The "create new record" endpoint.updateT
The "update record" endpoint.readT
The "get record" endpoint.destroyT
The "delete record" endpoint.Usage:
takeupT myEverestAdventure
--provider="Nepal Climbers Inc"
--Action.actionStatus=PotentialActionStatus
updateT JamaicaInn
--alternateName="The Most Famous Place in Cornwall"
readT photography
destroyT myFailedBusiness
Usage: <luteT> <subjectOf> <identifier>
OPEN QUESTION. CAN WE SHOULD WE DO THIS? <subjectOf> luteT <identifier>
Each takes two required/positional parameters for subjectOf
and identifier
. The identifier
is for the record you are listing. The subjectOf
is for the record whose list is to be engaged. Optional parameters for all other SchemaOrg properties.
listT
The "list all related records" endpoint.unlistT
The "remove existing record from list" endpoint.takeonT
As in "onboard". The "create and add new record to list" endpoint.enlistT
The "add existing record to list" endpoint.Optional parameters for listT
don't change data, they act as quick filters.
Usage:
# just list JPGs
listT photography
--mainEntityOfPage=VisualArtwork
--CreativeWork.encoding=JPG
# despite the initial plan: you're leaving heavySolarPanel behind
unlistT myEverestAdventure heavySolarPanel
# adding a childs play area to the Restaurant.
takeonT JamaicaInn childrensPlayArea
--mainEntityOfPage=Park
# try and rescue the business by going on holiday
enlistT myFailedBusiness myEverestAdventure
pingT
An endpoint for checking the availability of the server/cli and its endpoints.schemaT
An endpoint for getting metadata or for getting a new blank record.schemaT
takes one required/positional parameter being the SchemaType.
Usage:
# propercase version of the type gets you the meta schema
schemaT Thing
# lowercase gets you a blank thing
schemaT thing
loginT
An endpoint for "logging into" a thing.logoutT
An endpoint for "logging out" of an thing.Each takes one required/positional parameter for identifier
.
You won't ever log into the entire database system - you log into every thing separately. The thing is the app and the app is the thing.
NOT THIS Usage:
loginT elioway iambob letmein
takeupT jogging
takeupT curry
takeonT jogging trainers
takeonT jogging shorts
takeonT jogging tshirt
takeonT curry coconutmilk
takeonT curry chicken
takeonT curry curryPowder
logoutT elioway
THIS Usage:
takeupT jogging --Permit=myPermitForJogging
takeupT curry --Permit=myPermitForCurry
loginT jogging letmeintojogging
enlistT jogging trainers
enlistT jogging shorts
enlistT jogging tshirt
takeonT jogging partner
loginT curry letmeintocurry
takeonT curry coconutmilk
takeonT curry chicken
takeonT curry curryPowder
logout curry
logoutT jogging
With TEW you are only ever dealing with two levels. Top level is the engaged record. It's the one we mentioned in that "one to many".
This one thing - all its properties from Schema - can be edited by the TURDs, and its list can be manipulated by the LUTEs. If you want to edit a record which is listed, there isn't a special endpoint for that perse but since you can engage with any record you have listed you can use a TURD to update, destroy, or read it or a LUTE to work with its list.
You can even do this!
enlistT "007" "007"
Which is adding a record to its own list. This could cause infinite loops in some database systems. In ours that can't happen because recursion is limited to two levels.
We can easily iterate this pattern with no further endpoints because we're not listing anything different to the thing we engaged.
iterate needs no further explanation not already covered under engage and list.
While the TURDs and the LUTEs provide for 90% maybe 67% but definately not less than 34.3% of all data operations developers typically need to write, in many ways all the bread and butter work is in the 10% maybe 33% but definately not more than 65.7% of the data operations developers will need. Once an endpoint is written, it need only be imported or called and you can "chuck a thing at it".
Endpoints are highly reusable and are (quite technically) functional.
Basic reusuable TURDs and LUTEs, once done, will leave developers more time to write customised, functional, efficient, unit-tested endpoints specific to the apps purpose.
These data operations will be covered by the optimize stage of patterns.
The only constraint is that optimize endpoints must be TURDy or LUTEy. They will take the same positional and optional parameters of either (or no parameter). Those parameters will be in accordance to SchemaOrg.
All endpoints expect the whole "thing" and its entire list. For instance, if you have a particularly long list, and you are worried about your endpoints performance, you could prepare a filtered version of your "thing" - by removing irrelavant things listed. For example, an endpoint to tell you when your next flight is, isn't concerned with any Person
or BuddhistTemple
you have listed in the same data package.
But whether a slimmer version or not, you still pass in the engaged thing and its list:
At the very least every endpoint expect this:
{
"identifier": "1",
"ItemList": {
"itemListElement": [],
"itemListOrder": "",
"numberOfItems": 0
},
}
Each optimize endpoint will typically provide one feature.
TEW apps are simple alone, but because any endpoint expects the same data, and knows how to parse that data using Schema, it means data packages can be passed into different TEW apps. Complexity in TEW comes by iterating on simple operations between an engaged thing and its list.
Examples:
wikiAnAlbumT
is an endpoint (the author just made up in their head like magic) which takes the url
(of a wiki article) which is in the engaged "thing", and spiders that webpage to fill in blank properties and list in the app.takeupT Kind_of_Blue
--url=https://en.wikipedia.org/wiki/Kind_of_Blue
--mainEntityOfPage=MusicAlbum
wikiAnAlbumT Kind_of_Blue
listT Kind_of_Blue --mainEntityOfPage=MusicRecording
# outputs the track list of "Kind_of_Blue"
Here wikiAnAlbumT
was designed to locate the track listing of any Wiki entry of a music album, and add them to the Kind_of_Blue album app. That's all it was designed to do.
If you need a complex app you combine optimize endpoints.
takeupT Kind_of_Blue
--url=https://en.wikipedia.org/wiki/Kind_of_Blue
--mainEntityOfPage=MusicAlbum
wikiAnAlbumT Kind_of_Blue
updateT SoWhat --Review.reviewRating=4
updateT FreddieFreeloader --Review.reviewRating=2
updateT BlueinGreen --Review.reviewRating=5
updateT AllBlues --Review.reviewRating=4
updateT FlamencoSketches --Review.reviewRating=2
playFavouriteT Kind_of_Blue
listenedT BlueinGreen
listenedT SoWhat
listenedT FlamencoSketches
playLeastListenedT Kind_of_Blue
In TEW, apps and their data (aka the thing) are interchangeable. You could have ten favourite apps in your 10FavouriteApps App and I could have five favourite apps in my 5FavouriteApps App but one of the five apps is your 10FavouriteApps App.
Whatever correctly formatted TEW data you throw at any TEW endpoint won't break it. The worse that can happen is nothing.
Example:
Imagine you have a list of https://schema.org/Permits - a data package in TEW that you have stored recording common usernames and passwords you typically forget. There is nothing techically stopping you from loading that data into an app with the playFavouriteT
endpoint (used above to play the most played MP3 in the "Kind_of_Blue" tracklist).
In this example, playFavouriteT
simply won't find any records listed among your Permits with Schema relating https://schema.org/MusicRecording.
But you could enlistT
any MusicRecording. It will sit happily among the Permits in the list. playFavouriteT
will play it after finding it to be the favourite (after zero eliminations).
In clear terms: The app "thinks" it has the whole database in its data package; and all its operations