Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
API Tips from the Frontline
Search
Anna Filina
June 09, 2015
Programming
2
560
API Tips from the Frontline
Anna Filina
June 09, 2015
Tweet
Share
More Decks by Anna Filina
See All by Anna Filina
Surviving a Symfony Upgrade
afilina
0
91
Upgrading Legacy to the Latest PHP Version
afilina
1
150
Better Code Design in PHP
afilina
0
270
Semi-Automated Refactoring and Upgrades with Rector
afilina
0
170
Better Code Design in PHP
afilina
1
430
Better Code Design in PHP
afilina
0
590
Adding Tests to Untestable Legacy Code
afilina
0
380
Upgrading Legacy to the Latest PHP Version
afilina
0
390
Semi-Automated Refactoring and Upgrades with Rector
afilina
0
300
Other Decks in Programming
See All in Programming
AIエンジニアリングのご紹介 / Introduction to AI Engineering
rkaga
8
3.5k
Combinatorial Interview Problems with Backtracking Solutions - From Imperative Procedural Programming to Declarative Functional Programming - Part 2
philipschwarz
PRO
0
130
Canon EOS R50 V と R5 Mark II 購入でみえてきた最近のデジイチ VR180 事情、そして VR180 静止画に活路を見出すまで
karad
0
140
Spinner 軸ズレ現象を調べたらレンダリング深淵に飲まれた #レバテックMeetup
bengo4com
1
210
Flutter On-device AI로 완성하는 오프라인 앱, 박제창 @DevFest INCHEON 2025
itsmedreamwalker
1
170
AtCoder Conference 2025
shindannin
0
850
0→1 フロントエンド開発 Tips🚀 #レバテックMeetup
bengo4com
0
450
AI Agent Dojo #4: watsonx Orchestrate ADK体験
oniak3ibm
PRO
0
120
新卒エンジニアのプルリクエスト with AI駆動
fukunaga2025
0
240
Deno Tunnel を使ってみた話
kamekyame
0
290
CSC307 Lecture 02
javiergs
PRO
1
720
Cell-Based Architecture
larchanjo
0
150
Featured
See All Featured
Utilizing Notion as your number one productivity tool
mfonobong
2
190
Speed Design
sergeychernyshev
33
1.5k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.6k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.8k
HDC tutorial
michielstock
1
280
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
120
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
300
Discover your Explorer Soul
emna__ayadi
2
1k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
200
Raft: Consensus for Rubyists
vanstee
141
7.3k
Transcript
foolab.ca | @foolabca API Tips From the Frontline BEPHPUG, Berlin
- June 9, 2015
Anna Filina • Developer • Problem solver • Teacher •
Advisor • FooLab + ConFoo 2
What you will learn • Don't repeat my mistakes •
Overcome common obstacles • Build elegant & pragmatic APIs 3
Endpoints What URL to call when
Lists • /products • /products?category=games,movies&lang=fr • /products?include=platforms • /products?sort=-date •
/products?page[number]=2&page[size]=100 • /products?lang=fr 5
Details • /products/1 • /products/1?include=photos,reviews 6
Response example: list { "data": [ {"name": "Skyrim"}, {"name": "Civilization
V"} ], "page": { "number": 1, "size": 2, "pages": 50, "total": 100 } } 7
Write • POST /products • PUT or PATCH /products/1 •
DELETE /products/1 • Version your APIs: api.example.org/v1/products 8
Request/Response How to format stuff
Multiple formats • xml, json, etc. • Can use 1
endpoint with Accept header • Can send version, pagination & language info using headers too 10
Request • Bad: Content-Type: application/x-www-form-urlencoded • Content-Type: application/json • Send
content (POST) in body, not headers 11
Request example: add POST /products HTTP/1.1 Host: api.example.org Content-Type: application/json;
charset=UTF-8 { "data": { "name": "Skyrim", "price": 19.99 } } 12
Upload • Use tools, don't DIY (do it yourself). •
Client-side: Symfony • Client-side (more dynamic): Plupload • Step 1: upload temp file. • Step 2: give file path to next API request. • Server-side: Guzzle. 13
Plupload var uploader = new plupload.Uploader({ runtimes: 'html5,html4', max_file_size: '5mb',
url: '/api/upload', filters: [{extensions: 'jpg,png,jpeg'}] }); uploader.init(); 14
Guzzle <? $url = 'http://example.org/profiles/1/edit'; $request = $client->createRequest('PATCH', $url); $reqBody
= $request->getBody(); $reqBody->setField('data', ['first_name':'Anna']); $file = new PostFile('i.jpg', fopen('/path', 'r')); $reqBody->addFile($file); $response = $client->send($request); 15
Status codes • Don't confuse API & HTTP codes •
2xx success • 3xx redirect • 4xx client error • 5xx server error • Send API-specific code in body 16
Example of error Status: 400 Content-Type: application/json; charset=UTF-8 { "error":
{ "code": 1001, "message": "Price must be greater than 0." } } 17
Testing Simpler than you think
HTTP • Use Guzzle or built-in framework tool • Generate
HTTP request , compare output 19
Guzzle test // tests/ApiProductTest.php public function testGetOneProduct() { $client =
new Client(); $response = $client->get('http://example.org/products/1', [ 'exceptions' => false, 'headers' => ['Accept' => 'application/json'] ]); $this->assertEquals(200, $response->getStatusCode()); // ... } 20
Guzzle test // ... $body = $response->getBody()->getContents(); $this->assertJsonStringEqualsJsonString('{ "data": {
"id": "1", "name": "Skyrim", "price": 19.99 } }', $body); 21
Testing tips • Create separate database for tests • Write
tests before you code: • TDD • Contract between you and client dev 22
Authentication Nooo, I hate that part! Someone else code it
plz.
Multiple methods • Don't send username/password in each request ◦
Especially with untrusted 3rd parties ◦ Especially if no SSL • You can have multiple auth methods for one API • Sessions similar to tokens 24
OAuth2 • SSL required (can be risky) • Advanced features
like access scope • Can be overkill if you need basic features • Private credentials 25
OAuth2 - conceptual diagram 26 User Client app (php/js/mobile) API
Request Forward Validate Create token Store token Login form Login token user/pass
Digest • Its own encryption • Easy to implement •
No replay (nonce) • Comes out-of-the-box with some frameworks 27
Digest - conceptual diagram 28 Request User/client app API Unauthorized
Validate digest (nonce,pass) Request nonce
Refactoring to API Don't rewrite all the legacy at once
Progressive rewrite • Rewrite one component at a time •
Start with whatever has fewer dependencies (or critical) • Delete dead code • Copy production data for dev environment 30
Implementation tips Is this a good way to code it?
Libraries • I use Symfony & Doctrine • Aside from
frameworks, I prefer small tools that don't do too much magic 32
Reuse & standardize • Goal: streamline endpoint creation • Base
controller for common request processing • Base repository for querying with filters • Keep things fully customizable 33
Performance Make things faster. Much faster.
Benchmark • Give Tideways or Blackfire a spin • Make
performance part of your test suite • In dev/test mode, use a meta block 35
Example { "meta": { "perf": { "db_time": 0.00367, "total_time": 0.3120,
"memory": 19661 } } } 36
Performance tips • Don't use lazy loading. Example: $product->getPhotos(). •
Craft your own joins and carefully select fields. • Avoid ORM built-in hydration for read operations. 37
Performance tips • Use API keys even for public endpoints
(DDoS mitigation). • Put stuff in Memcached/Redis (especially blocked keys). • HTTP server can check headers 38
Useful links • Standard API format http://jsonapi.org/format/ • Digest implementation
http://php.net/manual/en/features.http-auth.php • Symfony components http://symfony.com/doc/current/components/index.html • Book "Build APIs You Won't Hate" https://leanpub.com/build-apis-you-wont-hate 39
Anna Filina • Development: PHP, JS, etc. • Fix problems:
bugs, performance, etc. • Workshops: testing, Symfony, AngularJS, API, etc. • Advisor: testing strategy, legacy code, etc. 40
@afilina afilina.com