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
580
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
API Tips from the Frontline
Anna Filina
June 09, 2015
More Decks by Anna Filina
See All by Anna Filina
Surviving a Symfony Upgrade
afilina
1
200
Upgrading Legacy to the Latest PHP Version
afilina
1
220
Better Code Design in PHP
afilina
0
320
Semi-Automated Refactoring and Upgrades with Rector
afilina
0
220
Better Code Design in PHP
afilina
1
470
Better Code Design in PHP
afilina
0
640
Adding Tests to Untestable Legacy Code
afilina
0
430
Upgrading Legacy to the Latest PHP Version
afilina
0
440
Semi-Automated Refactoring and Upgrades with Rector
afilina
0
350
Other Decks in Programming
See All in Programming
関数型プログラミングのメリットって何だろう?
wanko_it
0
200
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
210
AIが無かった頃の素敵な出会いの話
codmoninc
1
260
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
150
霧の中の代数的エフェクト
funnyycat
1
440
エンジニアにデザインハーネスを 〜デザインプロセスを規定するためのハーネス〜 / Design harness from an engineer's perspective
rkaga
2
1.8k
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
200
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
1
3.1k
Build-to-own AI: Agentic Development for Humans
inesmontani
PRO
0
100
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
550
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
260
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
170
Featured
See All Featured
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
410
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Designing for Performance
lara
611
70k
Un-Boring Meetings
codingconduct
0
350
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
470
Are puppies a ranking factor?
jonoalderson
1
3.7k
New Earth Scene 8
popppiees
3
2.4k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
430
Claude Code のすすめ
schroneko
67
230k
My Coaching Mixtape
mlcsv
0
180
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
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