by Peter Martin /
@pe7er
Joomladagen Nederland 2017 in Zeist,
zondag 2 april 2017
Peter Martin (@pe7er)
Lent (Nijmegen-Noord), Netherlands
www.db8.nl
Joomla support & development
Options Manager
(betaald Component)
- Importeer
instellingen van extensies in nieuwe website.
Organiseert:
* Linux Usergroup Nijmegen
* Open Coffee Nijmegen
Joomla vrijwilliger:
* Global Forum Moderator
* Joomla! Operations
Department Coordinator
* Mentor GSoC 2016 + 2017
* Joomla Bug Squad
* Pizza Bugs & Fun (in NL)
* voormalig Joomla Community
Leadership Team (6 yr)
Via User Interface
(browser)
https://www.google.nl/
maps/place/
Woudenbergseweg+54,
+3707HX+Zeist
Via Application Protocol Interface
https://maps.googleapis.com/
maps/api/geocode/json?sensor=false&address=
Woudenbergseweg%2054
%203707HX%20Zeist
{
"results" : [
{
"address_components" : [
{
"long_name" : "54",
"short_name" : "54",
"types" : [ "street_number" ]
}
],
"geometry" : {
"location" : {
"lat" : 52.086062,
"lng" : 5.281954199999999
},
1999 - SOAP (Simple Object Access Protocol)
+ WSDL (Web Services Description Language) (voorbeeld)
(Microsoft: Dave Winer, Don Box, Bob Atkinson, Mohsen Al-Ghosein)
WSDL File for HelloService
1999 - SOAP (Simple Object Access Protocol)
+ WSDL (Web Services Description Language) (voorbeeld)
(Microsoft: Dave Winer, Don Box, Bob Atkinson, Mohsen Al-Ghosein)
1998 - XML-RPC (XML via Remote Procedure Call)
(Dave Winer)
1999 - SOAP (Simple Object Access Protocol)
+ WSDL (Web Services Description Language) (voorbeeld)
(Microsoft: Dave Winer, Don Box, Bob Atkinson, Mohsen Al-Ghosein)
1998 - XML-RPC (XML via Remote Procedure Call)
(Dave Winer)
2000 - REST (REpresentational State Transfer)
ook wel RESTful Web services
(Roy Fielding:
Proefschrift)
INPUT: specifieke URL +
HTTP requests (POST, GET, PUT, DELETE, etc)
OUTPUT: HTTP status code +
gestructureerde data (bijv JSON)
1. Client-Server
2. Stateless
3. Cacheable
4. Layered system
5. Code on demand (optional)
6. Uniform interface
Separation of concerns
Scheiding UI & Data:
* portabiliteit: verschillende UIs
* schaalbaarheid: achterliggende data / servers
* UI & API los van elkaar kunnen ontwikkelen
Server bewaart geen context (geen cookies)
Elk request van Client
bevat alle data
Elk response van Server
bevat alle data
Response van GET is cacheable (POST etc niet)
Clients en servers regelen onderling cache
Client rechtstreeks Server
of via tussenstappen (Proxy, load balancer, etc)
Servers kunnen functionaliteit veranderen door code te verstrekken aan Client (bijv JavaScript).
HATEOAS - Hypermedia as the Engine of Application State
Response bevat alleen hyperlinks
voor mogelijke acties
Website met webapplicatie?
aankomst? -> log in
vertrek? -> log out
-> extra handelingen
dus onbetrouwbaar
behalve...
licht aan
jas uit
koffie
muziek aan
potje tafelvoetbal
verbinding maken op
laptop of
mobile
met Wi-Fi (LAN)
verbonden met LAN
bash script verzamelt
MAC adressen
van alle apparaten
stuurt die naar
externe webservice
Waarom niet?
Omdat het kan?
28 oktober 2015
REST API
in WordPress 4.4
Augustus 2015
mijn experimentje
op Joomla 3.4.3
(nog) geen REST API
SLIM Framework
extern PHP script; RESTFull
verbonden met
Joomla's database;
ontvangt en bewaart
MAC adressen
Maatwerk Component
beheer van
collega's +
MAC adressen
toont
aanwezigen...
Mobile App (Android)
maakt verbinding met
webservice
toont alle collega's
en hun aanwezigheid
een record:
GET - 1 of meer opvragen
POST – record aanmaken
PUT – update een record
DELETE – verwijderen
meervoud: /members/
ipv /member/
URL: /members/1
ipv /members.php?id=1
GEEN ww! maar woord + http request:
Toevoegen: /members/ + POST
ipv /members/add
Create - POST /members
Read - GET /members/1
Update - PUT /members/1
Delete - DELETE /members/1
List - GET /members
Employees -
GET /companies/X/members
XML document formaat:
* tekst georienteerd
* niet positie georienteerd
maar wel: tags, tags, tags, tags, tags, tags, tags, tags...
en closing tags: tags, tags, tags, tags, tags, tags, tags...
JSON: data formaat
* veel lichter dan XML
* whitespace buiten quotes -> ignored
Verschillende stijlen:
* JSON-API
* Twitter API
* Facebook API
{
"data": [{
"type": "employee",
"id": "1",
"attributes": { "name": "Maurice Moss" }
"relationships": {
"company": {
"links": {
"self": "http://example.com/employee/1/relationships/company",
"related": "http://example.com/company/1"
},
"data": { "type": "company", "id": "1" }
}
}
}
]
}
[
{
"id": "1",
"name": "Maurice Moss",
"company": "Reynholm Industries",
},
{
"id": "2",
"name": "Roy Trenneman",
"company": "Reynholm Industries",
}
]
{
"data": [
{
"id": "1",
"name": "Maurice Moss",
"company": "Reynholm Industries",
},
{
"id": "2",
"name": "Roy Trenneman",
"company": "Reynholm Industries",
}
]
}
{msg: [
{ id: "1",
name: "Maurice Moss",
company: "Reynholm Industries",
photo: "images/itcrowd/moss.jpg",
datetime: null
},
{ id: "2",
name: "Roy Trenneman",
company: "Reynholm Industries",
photo: "images/itcrowd/roy.jpg",
datetime: "2017-04-02 15:50:04"
} ],
error: false,
status: 200
}
Slim Framework v2
HTTP Status codes:
2xx - success
3xx - redirection
4xx - client errors
5xx - server errors
JSON-API errors
{
"errors": {
"code" : "1337",
"title": "Elite level needed",
"details": "Obviously you didn't played the game in the 1980s.",
"href": "http://example.com/docs/errors/1337"
}
}
Browser:
Postman (Chrome Add-on)
HttpFox (FireFox Add-on)
Network:
Wireshark
Fiddler
Charles (betaald)
URI of hostname:
http://example.com/api/v1/
http://v1.example.com/api/
HTTP body / URL query
{ "version" : "1.0" }
Request Header
APIversion: 1.0
Vary: APIversion
Content Negociation
Accept: application/vnd.myapp.v1+json
Geen versioning
1e versie nog niet verder doorontwikkeld.
Basic:
Username + Password
Digest:
MD5 hash
OAuth 1.0a
Access token exchange
public key + secret key
OAuth 2.0
SSL verplicht!
via URL of HTTP Request header
Security through obscurity
Beperk grootte
HTTP response
Query string
/members?limit=10
Geen pagination:
(nog) klein aantal medewerkers
Wat documenteren?
* API Endpoints
* Voorbeeld code
* Tutorial
Tools:
* API Blueprint
* RAML
* Swagger
/api/
{
msg: "Members API v1. README.md contains API information.",
error: false,
status: 200
}
/api/README.md
# Hubbels API v1
This application outputs JSON data. Use
- /members/ to display all members
- /members/:id to display a specific member
- /connections/ to display all connected members
### Version
3.0.2
JSON-LD
http://json-ld.org
* "Microdata" voor JSON
* definieert context
http://schema.org/ bevat ook JSON-LD voorbeelden.
{
"@context": "http://json-ld.org/contexts/person.jsonld",
"@id": "http://dbpedia.org/resource/John_Lennon",
"name": "John Lennon",
"born": "1940-10-09",
"spouse": "http://dbpedia.org/resource/Cynthia_Lennon"
}
Bron: http://json-ld.org
{"@context":
{
"Person": "http://xmlns.com/foaf/0.1/Person",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": "http://xmlns.com/foaf/0.1/name",
"nickname": "http://xmlns.com/foaf/0.1/nick",
"affiliation": "http://schema.org/affiliation",
"depiction":
{
"@id": "http://xmlns.com/foaf/0.1/depiction",
"@type": "@id"
},
"image":
{
"@id": "http://xmlns.com/foaf/0.1/img",
"@type": "@id"
},
Kwaliteit Open Data
Ontsluiting data:
1. vrij toegankelijk, in welk formaat dan ook.
2. in gestructureerd formaat (bijv Excel).
3. in Open Formaat (bijv CSV)
4. via een RESTful JSON API
5. via RESTful JSON-LD API
6. in het RDF (Resource Description Framework) formaat
Bron: Zes Sterren Model (Dimitri van Hees)
#!/bin/bash
# scan all MAC addresses in local network and send to external server
# (c) 2015 Peter Martin, db8.nl
MACS=$(sudo arp-scan --interface=eth0 --localnet -quiet | grep -E -o 'xdigit:{2}(:xdigit:{2}){5}')
array=(${MACS// / })
for i in "${!array[@]}"
do
MAC+="{\"mac\":\"${array[i]}\"},"
done
MAC="{\"macs\":["${MAC::-1}"]}"
curl -X POST -H "Content-Type: application/json" -d $MAC -i http://example.com/api/mac/
initialise();
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim(array(
'mode' => 'development'
));
$app->db = JFactory::getDbo();
$app->view(new \JsonApiView());
$app->add(new \JsonApiMiddleware());
//Main entry
$app->get('/', function () use ($app) {
$app->render(200, array(
'msg' => 'Members API v1. README.md contains API information.',
));
});
/* Members */
$app->map('/members/', function () use ($app) {
$query = $app->db->getQuery(true)
->select('#__db8members_members.id AS id, name, cat.title AS company, photo, datetime')
->from($app->db->quoteName('#__db8members_members'))
->leftjoin('#__db8members_devices ON #__db8members_devices.member_id = #__db8members_members.id')
->leftjoin('#__db8members_connections ON #__db8members_connections.mac = #__db8members_devices.mac')
->leftjoin('#__categories AS cat ON cat.id = #__db8members_members.catid')
->where('#__db8members_members.state = 1')
->order('#__db8members_members.name')
->group('#__db8members_members.id');
$app->db->setQuery($query);
$results = $app->db->loadObjectList();
$app->render(200, array( 'msg' => $results, ));
})->via('GET');
/* Member */
$app->map('/members/:id', function ($id) use ($app) {
$query = $app->db->getQuery(true)
->select('name, company, position, website')
->from($app->db->quoteName('#__db8members_members'))
->where('id = ' . $id)
->where('state = 1')
$app->db->setQuery($query);
$result = $app->db->loadObject();
$app->render(200, array(
'msg' => $result,
));
})->via('GET');
/* Connections */
$app->map('/mac/', function () use ($app) {
$request = $app->request();
$body = $request->getBody();
$macs = json_decode($body)->macs;
$results="";
//delete all records
$app->db->setQuery('TRUNCATE TABLE #__db8members_connections');
$app->db->execute();
//insert all mac addresses
$query = $app->db->getQuery(true);
$columns = array('id', 'mac', 'datetime');
$values = array();
$now =JFactory::getDate();
foreach ($macs as $mac)
{
$values[] = '0, "'.$mac->mac.'", "'.$now.'"';
}
$query->insert($app->db->quoteName('#__db8members_connections'));
$query->columns($columns);
$query->values($values);
$app->db->setQuery($query);
$app->db->query();
$app->render(200, array(
'msg' => $macs, //results,
));
})->via('POST');
$app->run();
Presentation:
http://slides.db8.nl
Peter Martin
e-mail: info at db8.nl
twitter: @pe7er
presentation: https://db8.nl
* API Evangelist
* Build APIs You Won't Hate - Philip Sturgeon
* REST API implementaties - Bèr Kessels
* http://json-ld.org
* Platform Linked Data Nederland
* Linked Data in HTML
Cat Sleeping Garden Domestic Brown Tabby Cute - Ranya, 2007
Cat Face Sleep Exhausted White Cat Pet - congerdesign, 2016
Digitization Null One Binary System Binary Digital - Gerd Altmann, 2017
The Sandwich
REST API in WordPress 4.4
Slim framework
Digging in permafrost - Nick Bonzey, 2007
Giving a gift - Yolanda DeLoach, 2015
Cables Wires, The Combination Of Connect - Michal Jarmoluk, 2012
CRUD Operations - Priya Darshini, 2013
Merge-split-transwiki default 2 - David Gothberg, 2008
Papertape - Poil, 2005
USS Kennedy - status board update - Mate Airman Casey Jones, 2002
Bending - Holotone, 2007
Continuous Versioning Strategy for Internal APIs - Bill Doerrfeld, 2017
Authenticate
Do Ostriches Really Bury Their Heads in the Sand? - wonderopolis
Text document with page number icon - Benjamin D. Esham, 2007
Ray en Anita (2 Unlimited) - ANP, 2015
No Limits (record sleeve) - 2 Unlimited
Bonanjo - Marta Pucciarelli, 2013
Glass ochem - Purpy Pupple, 2010
Confused Muddled Illogical Disoriented - Steve Buissinne, 2015
All other photos: Peter Martin