SlideShare a Scribd company logo
1 of 54
Download to read offline
Laravel
Kamil Kiełczewski
Właściciel
kamil.k.kielczewski@gmail.com
Zdjęcie
prelegenta
Agenda
1. Wprowadzenie
2. Przykład
3. Podsumowanie
Architektura Mikroserwisowa
Architektura Mikroserwisowa
Historia
REST (REpresentational State Transfer) - Roy Fielding doktorat "Architectural Styles
and the Design of Network-based Software Architectures" at UC Irvine, 2000
JSON (JavaScript Object Notation) - wyspecyfikowany przez Douglas Crockford
we wczesnych latach 2000
SOAP (Simple Object Access Protocol) : zaprojektowany przez Dave Winer, Don
Box, Bob Atkinson, Mohsen Al-Ghosein dla Microsoft, 1998
XML (eXtensible Markup Language) - wywodzi się z SGML (Charles Goldfarb,
Edward Mosher, Raymond Lorie, IBM, lata 1960), wielu autorów, 1996
Restful API - przykład
Metoda URL Opis
GET http://api.local/api/v1/movies zwraca listę filmów
POST http://api.local/api/v1/movies tworzy nowy film (z JSON)
GET http://api.local/api/v1/movies/:id zwraca detale filmu
PUT http://api.local/api/v1/movies/:id aktualizuje film (z JSON)
DELETE http://api.local/api/v1/movies/:id usuwa film
Restful API
GET http://api.local/api/v1/movies/123
{
"id": 123,
"title": "Rocky",
"year": 1976,
"genre": "drama",
"oscar": true,
"director": {...}
}
Problem
Jak opisywać API?
Gdzie przechowywać opis?
Historia
Excel/docks
Wiki / Jira / inne
Odpowiedź
Swagger - adnotacje w kodzie!
Historia
Swagger (api framewrok) - Tony Tam, 2010; OpenAPI (OA) 2016
Laravel (php framework) - Taylor Otwell, czerwiec 2011
Swagger-PHP (swagger.json gen from doctrine annotations ) styczeń 2015
Swagger-UI (UI gen from swagger.json) czerwiec 2011
DarkaOnLine/L5-Swagger (swagger-ui/php wrapper for L5) marzec 2015
Instalacja
laravel new api
cd api
composer require "darkaonline/l5-swagger:5.7.*"
php artisan vendor:publish --provider "L5SwaggerL5SwaggerServiceProvider"
config => api/config/l5-swagger.php
url => http://laravel-api.local/api/documentation
Przykład
.env:
# regenerate always
L5_SWAGGER_GENERATE_ALWAYS= true
/**
* @OAInfo(
* title="Laravel API", version="0.1", description="My api"
* )
*
* @OASecurityScheme(
* securityScheme="oauth2",
* type="oauth2",
* description="OAuth2 Password Grant",
* @OAFlow(
* flow="password",
* authorizationUrl="/oauth/authorize",
* tokenUrl="/oauth/token",
* refreshUrl="/oauth/token/refresh",
* scopes={"*": "ALL scopes"}
* )
* ),
*
* # first request to avoid swagger compilation err
* @OAGet(path="/test", @OAResponse(response="200",
* description="x",
* @OAJsonContent( type="json", example=
* {
* "name":"project",
* "items":{ 5, 6, {"a":1, "b":2, "c":{} } },
* }
* )),
* security={ {"oauth2": {"*"}} },
* )
*/
app/Http/Controllers/Controller.php:
Przykład
Przykład - konfiguracja
.env:
# sqlite db
DB_* (usuwamy/komentujemy wszystko z prefixem DB_ )
DB_CONNECTION=sqlite (dodajemy wpis)
cmd:
touch database/database.sqlite
Przykład - db
php artisan make:model Movie --migration
database/migrations/2018_11_16_230213_create_movies_table.php:
Schema::create('movies' , function (Blueprint $table) {
$table->increments ('id');
$table->unsignedInteger ('director_id' );
$table->string('title');
$table->integer('year');
$table->enum('genre', ['drama', 'comedy' , 'thriller' ]);
$table->boolean('oscar');
$table->timestamps ();
$table->foreign('director_id' )->references ('id')->on('directors' )->onDelete ('cascade' );
});
php artisan make:model Director --migration
database/migrations/2018_11_16_233410_create_directors_table.php:
Schema::create('directors' , function (Blueprint $table) {
$table->increments ('id');
$table->string('first_name' );
$table->string('last_name' );
$table->timestamps ();
});
php artisan migrate
Podtytuł 3
php artisan make:controller API/MovieController --api --model=Movie
php artisan make:controller API/DirectorController --api --model=Director
routes/api.php:
Route::group(['prefix'=>'v1'], function() {
Route::apiResource('movies', 'APIMovieController');
Route::apiResource('directors', 'APIDirectorController');
});
Przykład
/**
* @OASchema(
* @OAProperty( property="id", type="integer", example=3 ),
* @OAProperty( property="first_name", type="string", example="John" ),
* @OAProperty( property="last_name", type="string", example="Smith" ),
* @OAProperty( property="created_at", type="string", example="2018-10-21 19:13:37" ),
* @OAProperty( property="updated_at", type="string", example="2018-10-31 23:01:34" ),
*
* )
*/
class Director extends Model
{
protected $fillable = ['first_name', 'last_name'];
}
/**
* @OASchema(
* schema="DirectorEdit",
* @OAProperty( property="first_name", ref="#/components/schemas/Director/properties/first_name" ),
* @OAProperty( property="last_name", ref="#/components/schemas/Director/properties/last_name" ),
*
* )
*/
app/Director.php:
Przykład
Przykład
app/Http/Controllers/API/DirectorController.php
/**
* @OAGet(
* path="/api/v1/directors",
* tags={"director"},
* @OAResponse(response="200", description="list",
* @OAJsonContent( type="array", @OAItems( ref="#/components/schemas/Director" ))
* )
* )
*/
public function index()
{
return Director::all();
}
Przykład
Podtytuł 3
Przykład
app/Http/Controllers/API/DirectorController.php
/**
* @OAPost(
* path="/api/v1/directors",
* tags={"director"},
* @OARequestBody( required=true, @OAJsonContent(ref="#/components/schemas/DirectorEdit")),
* @OAResponse(response="201", description="director", @OAJsonContent( ref="#/components/schemas/Director") )
* )
*/
public function store(Request $request)
{
$director = Director::create($request->all());
return $director;
}
Podtytuł 3
Podtytuł 3
Przykład
app/Http/Controllers/API/DirectorController.php
/**
* @OAGet(
* path="/api/v1/directors/{director_id}", tags={"director"},
* @OAParameter(name="director_id", required=true, in="path", @OASchema( type="integer", example=1 ) ),
* @OAResponse(response="200", description="director", @OAJsonContent(ref="#/components/schemas/Director"))
* )
*/
public function show(Director $director)
{
return $director;
}
Podtytuł 3
Przykład
app/Http/Controllers/API/DirectorController.php
/**
* @OAPut(
* path="/api/v1/directors/{director_id}",
* tags={"director"},
* @OAParameter(name="director_id", required=true, in="path", @OASchema( type="integer", example=1 ) ),
* @OARequestBody( required=true, @OAJsonContent(ref="#/components/schemas/DirectorEdit")),
* @OAResponse(response="200", description="director", @OAJsonContent( ref="#/components/schemas/Director") )
* )
*/
public function update(Request $request, Director $director)
{
$director->fill($request->all())->save();
return $director;
}
Podtytuł 3
Przykład
app/Http/Controllers/API/DirectorController.php
/**
* @OADelete(
* path="/api/v1/directors/{director_id}", tags={"director"},
* @OAParameter(name="director_id", required=true, in="path", @OASchema( type="integer", example=1 ) ),
* @OAResponse(response="200", description="director", @OAJsonContent(ref="#/components/schemas/Director"))
* )
*/
public function destroy(Director $director)
{
$director->delete();
return $director;
}
Przykład
Przykład
Przykład
/**
* @OASchema(
* @OAProperty( property="id", type="integer", example=3 ),
* @OAProperty( property="director", ref="#/components/schemas/Director" ),
* @OAProperty( property="title", type="string", example="Rocky" ),
* @OAProperty( property="year", type="integer", example="1976" ),
* @OAProperty( property="genre", type="enum", enum={"drama", "comedy", "thriller"}, example="drama" ),
* @OAProperty( property="oscar", type="boolean", example=true ),
* @OAProperty( property="created_at", type="string", example="2018-10-21 19:13:37" ),
* @OAProperty( property="updated_at", type="string", example="2018-10-31 23:01:34" ),
*
* )
*/
class Movie extends Model
{
protected $fillable = ['director_id','title', 'year','genre','oscar'];
protected $hidden = ['director_id'];
public function director()
{
return $this->belongsTo('AppDirector');
}
}
app/Movie.php:
Przykład
/**
* @OASchema(
* schema="MovieEntry",
* @OAProperty( property="id", ref="#/components/schemas/Movie/properties/id" ),
* @OAProperty( property="title", ref="#/components/schemas/Movie/properties/title" ),
* @OAProperty( property="year", ref="#/components/schemas/Movie/properties/year" ),
* @OAProperty( property="genre", ref="#/components/schemas/Movie/properties/genre" ),
* @OAProperty( property="oscar", ref="#/components/schemas/Movie/properties/oscar" ),
* @OAProperty( property="created_at", ref="#/components/schemas/Movie/properties/created_at" ),
* @OAProperty( property="updated_at", ref="#/components/schemas/Movie/properties/updated_at" ),
* )
*/
/**
* @OASchema(
* schema="MovieEdit",
* @OAProperty( property="director_id", type="integer", example="1" ),
* @OAProperty( property="title", ref="#/components/schemas/Movie/properties/title" ),
* @OAProperty( property="year", ref="#/components/schemas/Movie/properties/year" ),
* @OAProperty( property="genre", ref="#/components/schemas/Movie/properties/genre" ),
* @OAProperty( property="oscar", ref="#/components/schemas/Movie/properties/oscar" ),
* )
*/
app/Movie.php:
Przykład
Przykład
/**
* @OAGet(
* path="/api/v1/movies",
* @OAParameter(name="genre", in="query", @OASchema( type="enum", enum={"drama", "comedy", "thriller"})),
* tags={"movie"},
* @OAResponse(response="200", description="list",
* @OAJsonContent( type="array", @OAItems( ref="#/components/schemas/MovieEntry" ))
* )
* )
*/
public function index()
{
$genre = request()->genre;
if($genre) {
return Movie::where('genre',$genre)->get();
} else {
return Movie::get();
}
}
app/Http/Controllers/API/MovieController.php:
Przykład
Przykład - multi-wybieralna lista
* @OAParameter(name="genre", in="query",
* @OASchema(
* type="array",
* @OAItems( type="enum", enum={"drama", "comedy", "thriller"} ),
* example={"drama"}
* )
* ),
Przykład
/**
* @OAPost(
* path="/api/v1/movies",
* tags={"movie"},
* @OARequestBody( required=true, @OAJsonContent(ref="#/components/schemas/MovieEdit")),
* @OAResponse(response="201", description="director", @OAJsonContent( ref="#/components/schemas/Movie") )
* )
*/
public function store(Request $request)
{
$director = Director::findOrFail($request->director_id);
$movie = Movie::create($request->all());
return $movie;
}
app/Http/Controllers/API/MovieController.php:
Przykład
Przykład
/**
* @OAGet(
* path="/api/v1/movies/{movie_id}", tags={"movie"},
* @OAParameter(name="movie_id", required=true, in="path", @OASchema( type="integer", example=1 ) ),
* @OAResponse(response="200", description="director", @OAJsonContent(ref="#/components/schemas/Movie"))
* )
*/
public function show(Movie $movie)
{
$movie->director; // load director to movie object
return $movie;
}
app/Http/Controllers/API/MovieController.php:
Przykład
Przykład
/**
* @OAPut(
* path="/api/v1/movies/{movie_id}",
* tags={"movie"},
* @OAParameter(name="movie_id", required=true, in="path", @OASchema( type="integer", example=1 ) ),
* @OARequestBody( required=true, @OAJsonContent(ref="#/components/schemas/MovieEdit")),
* @OAResponse(response="200", description="director", @OAJsonContent( ref="#/components/schemas/Movie") )
* )
*/
public function update(Request $request , Movie $movie)
{
$movie->fill($request ->all())->save();
return $movie;
}
/**
* @OADelete(
* path="/api/v1/movies/{movie_id}", tags={"movie"},
* @OAParameter(name="movie_id", required=true, in="path", @OASchema( type="integer", example=1 ) ),
* @OAResponse(response="200", description="director", @OAJsonContent(ref="#/components/schemas/MovieEntry"))
* )
*/
public function destroy(Movie $movie)
{
$movie->delete();
return $movie;
}
app/Http/Controllers/API/MovieController.php:
Przykład
Przykład
Przykład - swagger.json
{"openapi":"3.0.0","info":{"title":"Laravel API","description":"My
api","version":"0.1"},"paths":{"/api/v1/directors":{"get":{"tags":["director"],"operationId":"AppHttpControllersAPIDirectorController::index","responses":{"200":{"description":"list","content":{"a
pplication/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Director"}}}}}}},"post":{"tags":["director"],"operationId":"AppHttpControllersAPIDirectorController::store","re
questBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectorEdit"}}}},"responses":{"201":{"description":"director","content":{"application/json":{"sc
hema":{"$ref":"#/components/schemas/Director"}}}}}}},"/api/v1/directors/{director_id}":{"get":{"tags":["director"],"operationId":"AppHttpControllersAPIDirectorController::show","parameters":
[{"name":"director_id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"director","content":{"application/json":{"schema":{"$ref":"#/compone
nts/schemas/Director"}}}}}},"put":{"tags":["director"],"operationId":"AppHttpControllersAPIDirectorController::update","parameters":[{"name":"director_id","in":"path","required":true,"schema
":{"type":"integer","example":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectorEdit"}}}},"responses":{"200":{"description":"direct
or","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Director"}}}}}},"delete":{"tags":["director"],"operationId":"AppHttpControllersAPIDirectorController::destroy","para
meters":[{"name":"director_id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"director","content":{"application/json":{"schema":{"$ref":"#/c
omponents/schemas/Director"}}}}}}},"/api/v1/movies":{"get":{"tags":["movie"],"operationId":"AppHttpControllersAPIMovieController::index","parameters":[{"name":"genre","in":"query","sche
ma":{"type":"array","items":{"type":"enum","enum":["drama","comedy","thriller"]},"example":["drama"]}}],"responses":{"200":{"description":"list","content":{"application/json":{"schema":{"type":"arr
ay","items":{"$ref":"#/components/schemas/MovieEntry"}}}}}}},"post":{"tags":["movie"],"operationId":"AppHttpControllersAPIMovieController::store","requestBody":{"required":true,"content":
{"application/json":{"schema":{"$ref":"#/components/schemas/MovieEdit"}}}},"responses":{"201":{"description":"director","content":{"application/json":{"schema":{"$ref":"#/components/schemas/
Movie"}}}}}}},"/api/v1/movies/{movie_id}":{"get":{"tags":["movie"],"operationId":"AppHttpControllersAPIMovieController::show","parameters":[{"name":"movie_id","in":"path","required":true,"
schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"director","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Movie"}}}}}},"put":{"tags":["movie"],"
operationId":"AppHttpControllersAPIMovieController::update","parameters":[{"name":"movie_id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"requestBody":{"requir
ed":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MovieEdit"}}}},"responses":{"200":{"description":"director","content":{"application/json":{"schema":{"$ref":"#/com
ponents/schemas/Movie"}}}}}},"delete":{"tags":["movie"],"operationId":"AppHttpControllersAPIMovieController::destroy","parameters":[{"name":"movie_id","in":"path","required":true,"schem
a":{"type":"integer","example":1}}],"responses":{"200":{"description":"director","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MovieEntry"}}}}}}},"/test":{"get":{"responses
":{"200":{"description":"x","content":{"application/json":{"schema":{"type":"json"},"example":{"name":"project","items":[5,6,{"a":1,"b":2,"c":[]}]}}}}},"security":[{"oauth2":["*"]}]}}},"components":{"sche
mas":{"Director":{"properties":{"id":{"type":"integer","example":3},"first_name":{"type":"string","example":"John"},"last_name":{"type":"string","example":"Smith"},"created_at":{"type":"string","exa
mple":"2018-10-21 19:13:37"},"updated_at":{"type":"string","example":"2018-10-31
23:01:34"}},"type":"object"},"DirectorEdit":{"properties":{"first_name":{"$ref":"#/components/schemas/Director/properties/first_name"},"last_name":{"$ref":"#/components/schemas/Director/prop
erties/last_name"}},"type":"object"},"Movie":{"properties":{"id":{"type":"integer","example":3},"director":{"$ref":"#/components/schemas/Director"},"title":{"type":"string","example":"Rocky"},"year":
{"type":"integer","example":"1976"},"genre":{"type":"enum","enum":["drama","comedy","thriller"],"example":"drama"},"oscar":{"type":"boolean","example":true},"created_at":{"type":"string","exam
ple":"2018-10-21 19:13:37"},"updated_at":{"type":"string","example":"2018-10-31
23:01:34"}},"type":"object"},"MovieEntry":{"properties":{"id":{"$ref":"#/components/schemas/Movie/properties/id"},"title":{"$ref":"#/components/schemas/Movie/properties/title"},"year":{"$ref":"#/c
omponents/schemas/Movie/properties/year"},"genre":{"$ref":"#/components/schemas/Movie/properties/genre"},"oscar":{"$ref":"#/components/schemas/Movie/properties/oscar"},"created_at":{"
$ref":"#/components/schemas/Movie/properties/created_at"},"updated_at":{"$ref":"#/components/schemas/Movie/properties/updated_at"}},"type":"object"},"MovieEdit":{"properties":{"director_id
":{"type":"integer","example":"1"},"title":{"$ref":"#/components/schemas/Movie/properties/title"},"year":{"$ref":"#/components/schemas/Movie/properties/year"},"genre":{"$ref":"#/components/sch
emas/Movie/properties/genre"},"oscar":{"$ref":"#/components/schemas/Movie/properties/oscar"}},"type":"object"}},"securitySchemes":{"oauth2":{"type":"oauth2","description":"OAuth2
Password Grant","flows":{"password":{"authorizationUrl":"/oauth/authorize","tokenUrl":"/oauth/token","refreshUrl":"/oauth/token/refresh","scopes":{"*":"ALL scopes"}}}}}}}
Podsumowanie
Plusy opisywania API za pomocą swaggera w L5:
1. Wersjonowanie opisu (git)
2. Wszystko pod ręką (w kodzie)
3. Publikowanie opisu API bezpośrednio w aplikcji
4. Generyczne UI dla ręcznego testowania API
5. Generowanie swagger JSON/YAML dla innych narzędzi
(np. testowania automatycznego, generowania klientów
api dla angular etc.)
6. Wsparcie dla oauth2
Bonus - Pozycja
Krzesło - pomyłka...
Bonus - Pozycja
Piłka 55cm (~50zł)
Prosta pozycja:
- zdrowy kręgosłup
- głębszy oddech (wydech)
- lepsze krążenie
- brak nacisku na narz. wew.
- więcej energii
Prosta pozycja wywoła na początku ból
nieprzyzwyczajonych mięśni. Oswajanie się:
1 tydzień - 15 min/dziennie,
2 tydzien - 30 min/dziennie,
...
6 tydzień - 8 godz/dziennie
- Wyciągamy czubek głowy by “podnieść nim sufit”
- Broda nisko, blisko szyi.
- Uszy równo z barkami a nos w linii z pępkiem
- Kolana niżej niż biodra
- Brzuch blisko krawędzi biurka
- Brak oparcia dla pleców, ekran centralnie z przodu
- Czubek ekranu na wysokości czubka głowy-wzroku
- Piłka mocno napompowana
wzorcowo
Bonus - Pozycja
Piłka - Błędy
- za daleko od stołu
(powoduje z czasem
pochylenie do przodu)
- miękka piłka
- za nisko ekran
- za nisko ekran
powoduje z czasem
zginanie szyi w dół
- ekran z boku
- za daleko od stołu
- miękka piłka
Bonus - Pozycja
Podsumowanie
Pytania?
Ta prezentacja: https://is.gd/QTjqXE
Kamil Kiełczewski
kamil.k.kielczewski@gmail.com
airavana.net

More Related Content

What's hot

NodeJS guide for beginners
NodeJS guide for beginnersNodeJS guide for beginners
NodeJS guide for beginnersEnoch Joshua
 
Web Application Frameworks - Web Technologies (1019888BNR)
Web Application Frameworks - Web Technologies (1019888BNR)Web Application Frameworks - Web Technologies (1019888BNR)
Web Application Frameworks - Web Technologies (1019888BNR)Beat Signer
 
Part One: Building Web Apps with the MERN Stack
Part One: Building Web Apps with the MERN StackPart One: Building Web Apps with the MERN Stack
Part One: Building Web Apps with the MERN StackMongoDB
 
Mobile development with Flutter
Mobile development with FlutterMobile development with Flutter
Mobile development with FlutterAwok
 
Android structure
Android structureAndroid structure
Android structureKumar
 
만화경 앱 개발기(iOS)
만화경 앱 개발기(iOS)만화경 앱 개발기(iOS)
만화경 앱 개발기(iOS)ssuserb942d2
 
Windows 11 がやってくる - IT管理者の準備と対策
Windows 11 がやってくる -  IT管理者の準備と対策Windows 11 がやってくる -  IT管理者の準備と対策
Windows 11 がやってくる - IT管理者の準備と対策彰 村地
 
Intro to react native
Intro to react nativeIntro to react native
Intro to react nativeModusJesus
 
Layouts in android
Layouts in androidLayouts in android
Layouts in androidDurai S
 
Windows Server and Docker - The Internals Behind Bringing Docker and Containe...
Windows Server and Docker - The Internals Behind Bringing Docker and Containe...Windows Server and Docker - The Internals Behind Bringing Docker and Containe...
Windows Server and Docker - The Internals Behind Bringing Docker and Containe...Docker, Inc.
 
Publish Android Application on Google Play Store
Publish Android Application on Google Play Store Publish Android Application on Google Play Store
Publish Android Application on Google Play Store Sandip Kalola
 
Mobile Development Lifecycle
Mobile Development LifecycleMobile Development Lifecycle
Mobile Development LifecycleNUS-ISS
 
2022 APIsecure_Method for exploiting IDOR on nodejs+mongodb based backend
2022 APIsecure_Method for exploiting IDOR on nodejs+mongodb based backend2022 APIsecure_Method for exploiting IDOR on nodejs+mongodb based backend
2022 APIsecure_Method for exploiting IDOR on nodejs+mongodb based backendAPIsecure_ Official
 
How Insurance Companies Use MongoDB
How Insurance Companies Use MongoDB How Insurance Companies Use MongoDB
How Insurance Companies Use MongoDB MongoDB
 
React workshop presentation
React workshop presentationReact workshop presentation
React workshop presentationBojan Golubović
 
Basics of MongoDB
Basics of MongoDB Basics of MongoDB
Basics of MongoDB Habilelabs
 

What's hot (20)

NodeJS guide for beginners
NodeJS guide for beginnersNodeJS guide for beginners
NodeJS guide for beginners
 
Web Application Frameworks - Web Technologies (1019888BNR)
Web Application Frameworks - Web Technologies (1019888BNR)Web Application Frameworks - Web Technologies (1019888BNR)
Web Application Frameworks - Web Technologies (1019888BNR)
 
Part One: Building Web Apps with the MERN Stack
Part One: Building Web Apps with the MERN StackPart One: Building Web Apps with the MERN Stack
Part One: Building Web Apps with the MERN Stack
 
Mobile development with Flutter
Mobile development with FlutterMobile development with Flutter
Mobile development with Flutter
 
Android structure
Android structureAndroid structure
Android structure
 
만화경 앱 개발기(iOS)
만화경 앱 개발기(iOS)만화경 앱 개발기(iOS)
만화경 앱 개발기(iOS)
 
Windows 11 がやってくる - IT管理者の準備と対策
Windows 11 がやってくる -  IT管理者の準備と対策Windows 11 がやってくる -  IT管理者の準備と対策
Windows 11 がやってくる - IT管理者の準備と対策
 
Angular material
Angular materialAngular material
Angular material
 
Intro to react native
Intro to react nativeIntro to react native
Intro to react native
 
CSharp.ppt
CSharp.pptCSharp.ppt
CSharp.ppt
 
Layouts in android
Layouts in androidLayouts in android
Layouts in android
 
Windows Server and Docker - The Internals Behind Bringing Docker and Containe...
Windows Server and Docker - The Internals Behind Bringing Docker and Containe...Windows Server and Docker - The Internals Behind Bringing Docker and Containe...
Windows Server and Docker - The Internals Behind Bringing Docker and Containe...
 
Publish Android Application on Google Play Store
Publish Android Application on Google Play Store Publish Android Application on Google Play Store
Publish Android Application on Google Play Store
 
Mobile Development Lifecycle
Mobile Development LifecycleMobile Development Lifecycle
Mobile Development Lifecycle
 
2022 APIsecure_Method for exploiting IDOR on nodejs+mongodb based backend
2022 APIsecure_Method for exploiting IDOR on nodejs+mongodb based backend2022 APIsecure_Method for exploiting IDOR on nodejs+mongodb based backend
2022 APIsecure_Method for exploiting IDOR on nodejs+mongodb based backend
 
How Insurance Companies Use MongoDB
How Insurance Companies Use MongoDB How Insurance Companies Use MongoDB
How Insurance Companies Use MongoDB
 
Introduction to Eclipse IDE
Introduction to Eclipse IDEIntroduction to Eclipse IDE
Introduction to Eclipse IDE
 
React workshop presentation
React workshop presentationReact workshop presentation
React workshop presentation
 
Computer virus
Computer virusComputer virus
Computer virus
 
Basics of MongoDB
Basics of MongoDB Basics of MongoDB
Basics of MongoDB
 

Similar to Laravel dokumentacja Restful API - swagger

Exploring Symfony's Code
Exploring Symfony's CodeExploring Symfony's Code
Exploring Symfony's CodeWildan Maulana
 
Web Components With Rails
Web Components With RailsWeb Components With Rails
Web Components With RailsBoris Nadion
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
Developing RESTful WebServices using Jersey
Developing RESTful WebServices using JerseyDeveloping RESTful WebServices using Jersey
Developing RESTful WebServices using Jerseyb_kathir
 
Intorduction of Playframework
Intorduction of PlayframeworkIntorduction of Playframework
Intorduction of Playframeworkmaltiyadav
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLsintelliyole
 
Crafting Evolvable Api Responses
Crafting Evolvable Api ResponsesCrafting Evolvable Api Responses
Crafting Evolvable Api Responsesdarrelmiller71
 
Flask and Angular: An approach to build robust platforms
Flask and Angular:  An approach to build robust platformsFlask and Angular:  An approach to build robust platforms
Flask and Angular: An approach to build robust platformsAyush Sharma
 
Intoduction on Playframework
Intoduction on PlayframeworkIntoduction on Playframework
Intoduction on PlayframeworkKnoldus Inc.
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAERon Reiter
 
node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascriptEldar Djafarov
 

Similar to Laravel dokumentacja Restful API - swagger (20)

Doctrine for NoSQL
Doctrine for NoSQLDoctrine for NoSQL
Doctrine for NoSQL
 
Doctrine and NoSQL
Doctrine and NoSQLDoctrine and NoSQL
Doctrine and NoSQL
 
Intro to Sail.js
Intro to Sail.jsIntro to Sail.js
Intro to Sail.js
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
Exploring Symfony's Code
Exploring Symfony's CodeExploring Symfony's Code
Exploring Symfony's Code
 
Web Components With Rails
Web Components With RailsWeb Components With Rails
Web Components With Rails
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Developing RESTful WebServices using Jersey
Developing RESTful WebServices using JerseyDeveloping RESTful WebServices using Jersey
Developing RESTful WebServices using Jersey
 
Intorduction of Playframework
Intorduction of PlayframeworkIntorduction of Playframework
Intorduction of Playframework
 
Spring boot
Spring boot Spring boot
Spring boot
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Scripting GeoServer
Scripting GeoServerScripting GeoServer
Scripting GeoServer
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLs
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
 
Crafting Evolvable Api Responses
Crafting Evolvable Api ResponsesCrafting Evolvable Api Responses
Crafting Evolvable Api Responses
 
Flask and Angular: An approach to build robust platforms
Flask and Angular:  An approach to build robust platformsFlask and Angular:  An approach to build robust platforms
Flask and Angular: An approach to build robust platforms
 
Play 2.0
Play 2.0Play 2.0
Play 2.0
 
Intoduction on Playframework
Intoduction on PlayframeworkIntoduction on Playframework
Intoduction on Playframework
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAE
 
node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascript
 

More from Laravel Poland MeetUp

WebRTC+Websockety - Jak stworzyłem aplikację do kamerek internetowych w Larav...
WebRTC+Websockety - Jak stworzyłem aplikację do kamerek internetowych w Larav...WebRTC+Websockety - Jak stworzyłem aplikację do kamerek internetowych w Larav...
WebRTC+Websockety - Jak stworzyłem aplikację do kamerek internetowych w Larav...Laravel Poland MeetUp
 
Kilka slajdów o castowaniu atrybutów w Eloquent
Kilka slajdów o castowaniu atrybutów w EloquentKilka slajdów o castowaniu atrybutów w Eloquent
Kilka slajdów o castowaniu atrybutów w EloquentLaravel Poland MeetUp
 
Jak przyspieszyłem aplikację produkcyjną o ponad 40%
Jak przyspieszyłem aplikację produkcyjną o ponad 40%Jak przyspieszyłem aplikację produkcyjną o ponad 40%
Jak przyspieszyłem aplikację produkcyjną o ponad 40%Laravel Poland MeetUp
 
Cykl życia zapytania HTTP (pod maską)
Cykl życia zapytania HTTP (pod maską)Cykl życia zapytania HTTP (pod maską)
Cykl życia zapytania HTTP (pod maską)Laravel Poland MeetUp
 
Enumy w Laravelu - dlaczego warto stosować?
Enumy w Laravelu - dlaczego warto stosować?Enumy w Laravelu - dlaczego warto stosować?
Enumy w Laravelu - dlaczego warto stosować?Laravel Poland MeetUp
 
Laravelowe paczki do uwierzytelniania
Laravelowe paczki do uwierzytelnianiaLaravelowe paczki do uwierzytelniania
Laravelowe paczki do uwierzytelnianiaLaravel Poland MeetUp
 
Przegląd najciekawszych wtyczek do Laravela
Przegląd najciekawszych wtyczek do LaravelaPrzegląd najciekawszych wtyczek do Laravela
Przegląd najciekawszych wtyczek do LaravelaLaravel Poland MeetUp
 
Laravel Dusk - prosty przepis na testy E2E
Laravel Dusk - prosty przepis na testy E2ELaravel Dusk - prosty przepis na testy E2E
Laravel Dusk - prosty przepis na testy E2ELaravel Poland MeetUp
 
Laravel Octane - czy na pewno taki szybki?
Laravel Octane - czy na pewno taki szybki?Laravel Octane - czy na pewno taki szybki?
Laravel Octane - czy na pewno taki szybki?Laravel Poland MeetUp
 
Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPLaravel Poland MeetUp
 
Wstęp do Gitlab CI/CD w aplikacjach napisanych w Laravel
Wstęp do Gitlab CI/CD w aplikacjach napisanych w LaravelWstęp do Gitlab CI/CD w aplikacjach napisanych w Laravel
Wstęp do Gitlab CI/CD w aplikacjach napisanych w LaravelLaravel Poland MeetUp
 
Laravel Collection - tablice na sterydach
Laravel Collection - tablice na sterydachLaravel Collection - tablice na sterydach
Laravel Collection - tablice na sterydachLaravel Poland MeetUp
 

More from Laravel Poland MeetUp (20)

WebRTC+Websockety - Jak stworzyłem aplikację do kamerek internetowych w Larav...
WebRTC+Websockety - Jak stworzyłem aplikację do kamerek internetowych w Larav...WebRTC+Websockety - Jak stworzyłem aplikację do kamerek internetowych w Larav...
WebRTC+Websockety - Jak stworzyłem aplikację do kamerek internetowych w Larav...
 
Kilka slajdów o castowaniu atrybutów w Eloquent
Kilka slajdów o castowaniu atrybutów w EloquentKilka slajdów o castowaniu atrybutów w Eloquent
Kilka slajdów o castowaniu atrybutów w Eloquent
 
Licencje otwartego oprogramowania
Licencje otwartego oprogramowaniaLicencje otwartego oprogramowania
Licencje otwartego oprogramowania
 
Jak przyspieszyłem aplikację produkcyjną o ponad 40%
Jak przyspieszyłem aplikację produkcyjną o ponad 40%Jak przyspieszyłem aplikację produkcyjną o ponad 40%
Jak przyspieszyłem aplikację produkcyjną o ponad 40%
 
Jak przemycić Shape Up do Scruma?
Jak przemycić Shape Up do Scruma?Jak przemycić Shape Up do Scruma?
Jak przemycić Shape Up do Scruma?
 
Cykl życia zapytania HTTP (pod maską)
Cykl życia zapytania HTTP (pod maską)Cykl życia zapytania HTTP (pod maską)
Cykl życia zapytania HTTP (pod maską)
 
Enumy w Laravelu - dlaczego warto stosować?
Enumy w Laravelu - dlaczego warto stosować?Enumy w Laravelu - dlaczego warto stosować?
Enumy w Laravelu - dlaczego warto stosować?
 
Laravelowe paczki do uwierzytelniania
Laravelowe paczki do uwierzytelnianiaLaravelowe paczki do uwierzytelniania
Laravelowe paczki do uwierzytelniania
 
Przegląd najciekawszych wtyczek do Laravela
Przegląd najciekawszych wtyczek do LaravelaPrzegląd najciekawszych wtyczek do Laravela
Przegląd najciekawszych wtyczek do Laravela
 
Walidacja w Laravelu
Walidacja w LaraveluWalidacja w Laravelu
Walidacja w Laravelu
 
(prawie) Wszystko o Tinkerze
(prawie) Wszystko o Tinkerze(prawie) Wszystko o Tinkerze
(prawie) Wszystko o Tinkerze
 
Laravel Dusk - prosty przepis na testy E2E
Laravel Dusk - prosty przepis na testy E2ELaravel Dusk - prosty przepis na testy E2E
Laravel Dusk - prosty przepis na testy E2E
 
Laravel Octane - czy na pewno taki szybki?
Laravel Octane - czy na pewno taki szybki?Laravel Octane - czy na pewno taki szybki?
Laravel Octane - czy na pewno taki szybki?
 
Laravel Jobs i PHP8
Laravel Jobs i PHP8Laravel Jobs i PHP8
Laravel Jobs i PHP8
 
Wszystko o Laravel Livewire
Wszystko o Laravel Livewire Wszystko o Laravel Livewire
Wszystko o Laravel Livewire
 
Laravel/PHP - zderzenie z PDFami
Laravel/PHP - zderzenie z PDFamiLaravel/PHP - zderzenie z PDFami
Laravel/PHP - zderzenie z PDFami
 
Action-based Laravel
Action-based LaravelAction-based Laravel
Action-based Laravel
 
Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHP
 
Wstęp do Gitlab CI/CD w aplikacjach napisanych w Laravel
Wstęp do Gitlab CI/CD w aplikacjach napisanych w LaravelWstęp do Gitlab CI/CD w aplikacjach napisanych w Laravel
Wstęp do Gitlab CI/CD w aplikacjach napisanych w Laravel
 
Laravel Collection - tablice na sterydach
Laravel Collection - tablice na sterydachLaravel Collection - tablice na sterydach
Laravel Collection - tablice na sterydach
 

Recently uploaded

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfngoud9212
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 

Recently uploaded (20)

DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdf
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 

Laravel dokumentacja Restful API - swagger

  • 6. Historia REST (REpresentational State Transfer) - Roy Fielding doktorat "Architectural Styles and the Design of Network-based Software Architectures" at UC Irvine, 2000 JSON (JavaScript Object Notation) - wyspecyfikowany przez Douglas Crockford we wczesnych latach 2000 SOAP (Simple Object Access Protocol) : zaprojektowany przez Dave Winer, Don Box, Bob Atkinson, Mohsen Al-Ghosein dla Microsoft, 1998 XML (eXtensible Markup Language) - wywodzi się z SGML (Charles Goldfarb, Edward Mosher, Raymond Lorie, IBM, lata 1960), wielu autorów, 1996
  • 7. Restful API - przykład Metoda URL Opis GET http://api.local/api/v1/movies zwraca listę filmów POST http://api.local/api/v1/movies tworzy nowy film (z JSON) GET http://api.local/api/v1/movies/:id zwraca detale filmu PUT http://api.local/api/v1/movies/:id aktualizuje film (z JSON) DELETE http://api.local/api/v1/movies/:id usuwa film
  • 8. Restful API GET http://api.local/api/v1/movies/123 { "id": 123, "title": "Rocky", "year": 1976, "genre": "drama", "oscar": true, "director": {...} }
  • 9. Problem Jak opisywać API? Gdzie przechowywać opis?
  • 12. Historia Swagger (api framewrok) - Tony Tam, 2010; OpenAPI (OA) 2016 Laravel (php framework) - Taylor Otwell, czerwiec 2011 Swagger-PHP (swagger.json gen from doctrine annotations ) styczeń 2015 Swagger-UI (UI gen from swagger.json) czerwiec 2011 DarkaOnLine/L5-Swagger (swagger-ui/php wrapper for L5) marzec 2015
  • 13. Instalacja laravel new api cd api composer require "darkaonline/l5-swagger:5.7.*" php artisan vendor:publish --provider "L5SwaggerL5SwaggerServiceProvider" config => api/config/l5-swagger.php url => http://laravel-api.local/api/documentation
  • 14. Przykład .env: # regenerate always L5_SWAGGER_GENERATE_ALWAYS= true /** * @OAInfo( * title="Laravel API", version="0.1", description="My api" * ) * * @OASecurityScheme( * securityScheme="oauth2", * type="oauth2", * description="OAuth2 Password Grant", * @OAFlow( * flow="password", * authorizationUrl="/oauth/authorize", * tokenUrl="/oauth/token", * refreshUrl="/oauth/token/refresh", * scopes={"*": "ALL scopes"} * ) * ), * * # first request to avoid swagger compilation err * @OAGet(path="/test", @OAResponse(response="200", * description="x", * @OAJsonContent( type="json", example= * { * "name":"project", * "items":{ 5, 6, {"a":1, "b":2, "c":{} } }, * } * )), * security={ {"oauth2": {"*"}} }, * ) */ app/Http/Controllers/Controller.php:
  • 16. Przykład - konfiguracja .env: # sqlite db DB_* (usuwamy/komentujemy wszystko z prefixem DB_ ) DB_CONNECTION=sqlite (dodajemy wpis) cmd: touch database/database.sqlite
  • 17. Przykład - db php artisan make:model Movie --migration database/migrations/2018_11_16_230213_create_movies_table.php: Schema::create('movies' , function (Blueprint $table) { $table->increments ('id'); $table->unsignedInteger ('director_id' ); $table->string('title'); $table->integer('year'); $table->enum('genre', ['drama', 'comedy' , 'thriller' ]); $table->boolean('oscar'); $table->timestamps (); $table->foreign('director_id' )->references ('id')->on('directors' )->onDelete ('cascade' ); }); php artisan make:model Director --migration database/migrations/2018_11_16_233410_create_directors_table.php: Schema::create('directors' , function (Blueprint $table) { $table->increments ('id'); $table->string('first_name' ); $table->string('last_name' ); $table->timestamps (); }); php artisan migrate
  • 18. Podtytuł 3 php artisan make:controller API/MovieController --api --model=Movie php artisan make:controller API/DirectorController --api --model=Director routes/api.php: Route::group(['prefix'=>'v1'], function() { Route::apiResource('movies', 'APIMovieController'); Route::apiResource('directors', 'APIDirectorController'); });
  • 19. Przykład /** * @OASchema( * @OAProperty( property="id", type="integer", example=3 ), * @OAProperty( property="first_name", type="string", example="John" ), * @OAProperty( property="last_name", type="string", example="Smith" ), * @OAProperty( property="created_at", type="string", example="2018-10-21 19:13:37" ), * @OAProperty( property="updated_at", type="string", example="2018-10-31 23:01:34" ), * * ) */ class Director extends Model { protected $fillable = ['first_name', 'last_name']; } /** * @OASchema( * schema="DirectorEdit", * @OAProperty( property="first_name", ref="#/components/schemas/Director/properties/first_name" ), * @OAProperty( property="last_name", ref="#/components/schemas/Director/properties/last_name" ), * * ) */ app/Director.php:
  • 21. Przykład app/Http/Controllers/API/DirectorController.php /** * @OAGet( * path="/api/v1/directors", * tags={"director"}, * @OAResponse(response="200", description="list", * @OAJsonContent( type="array", @OAItems( ref="#/components/schemas/Director" )) * ) * ) */ public function index() { return Director::all(); }
  • 24. Przykład app/Http/Controllers/API/DirectorController.php /** * @OAPost( * path="/api/v1/directors", * tags={"director"}, * @OARequestBody( required=true, @OAJsonContent(ref="#/components/schemas/DirectorEdit")), * @OAResponse(response="201", description="director", @OAJsonContent( ref="#/components/schemas/Director") ) * ) */ public function store(Request $request) { $director = Director::create($request->all()); return $director; }
  • 27. Przykład app/Http/Controllers/API/DirectorController.php /** * @OAGet( * path="/api/v1/directors/{director_id}", tags={"director"}, * @OAParameter(name="director_id", required=true, in="path", @OASchema( type="integer", example=1 ) ), * @OAResponse(response="200", description="director", @OAJsonContent(ref="#/components/schemas/Director")) * ) */ public function show(Director $director) { return $director; }
  • 29. Przykład app/Http/Controllers/API/DirectorController.php /** * @OAPut( * path="/api/v1/directors/{director_id}", * tags={"director"}, * @OAParameter(name="director_id", required=true, in="path", @OASchema( type="integer", example=1 ) ), * @OARequestBody( required=true, @OAJsonContent(ref="#/components/schemas/DirectorEdit")), * @OAResponse(response="200", description="director", @OAJsonContent( ref="#/components/schemas/Director") ) * ) */ public function update(Request $request, Director $director) { $director->fill($request->all())->save(); return $director; }
  • 31. Przykład app/Http/Controllers/API/DirectorController.php /** * @OADelete( * path="/api/v1/directors/{director_id}", tags={"director"}, * @OAParameter(name="director_id", required=true, in="path", @OASchema( type="integer", example=1 ) ), * @OAResponse(response="200", description="director", @OAJsonContent(ref="#/components/schemas/Director")) * ) */ public function destroy(Director $director) { $director->delete(); return $director; }
  • 34. Przykład /** * @OASchema( * @OAProperty( property="id", type="integer", example=3 ), * @OAProperty( property="director", ref="#/components/schemas/Director" ), * @OAProperty( property="title", type="string", example="Rocky" ), * @OAProperty( property="year", type="integer", example="1976" ), * @OAProperty( property="genre", type="enum", enum={"drama", "comedy", "thriller"}, example="drama" ), * @OAProperty( property="oscar", type="boolean", example=true ), * @OAProperty( property="created_at", type="string", example="2018-10-21 19:13:37" ), * @OAProperty( property="updated_at", type="string", example="2018-10-31 23:01:34" ), * * ) */ class Movie extends Model { protected $fillable = ['director_id','title', 'year','genre','oscar']; protected $hidden = ['director_id']; public function director() { return $this->belongsTo('AppDirector'); } } app/Movie.php:
  • 35. Przykład /** * @OASchema( * schema="MovieEntry", * @OAProperty( property="id", ref="#/components/schemas/Movie/properties/id" ), * @OAProperty( property="title", ref="#/components/schemas/Movie/properties/title" ), * @OAProperty( property="year", ref="#/components/schemas/Movie/properties/year" ), * @OAProperty( property="genre", ref="#/components/schemas/Movie/properties/genre" ), * @OAProperty( property="oscar", ref="#/components/schemas/Movie/properties/oscar" ), * @OAProperty( property="created_at", ref="#/components/schemas/Movie/properties/created_at" ), * @OAProperty( property="updated_at", ref="#/components/schemas/Movie/properties/updated_at" ), * ) */ /** * @OASchema( * schema="MovieEdit", * @OAProperty( property="director_id", type="integer", example="1" ), * @OAProperty( property="title", ref="#/components/schemas/Movie/properties/title" ), * @OAProperty( property="year", ref="#/components/schemas/Movie/properties/year" ), * @OAProperty( property="genre", ref="#/components/schemas/Movie/properties/genre" ), * @OAProperty( property="oscar", ref="#/components/schemas/Movie/properties/oscar" ), * ) */ app/Movie.php:
  • 37. Przykład /** * @OAGet( * path="/api/v1/movies", * @OAParameter(name="genre", in="query", @OASchema( type="enum", enum={"drama", "comedy", "thriller"})), * tags={"movie"}, * @OAResponse(response="200", description="list", * @OAJsonContent( type="array", @OAItems( ref="#/components/schemas/MovieEntry" )) * ) * ) */ public function index() { $genre = request()->genre; if($genre) { return Movie::where('genre',$genre)->get(); } else { return Movie::get(); } } app/Http/Controllers/API/MovieController.php:
  • 39. Przykład - multi-wybieralna lista * @OAParameter(name="genre", in="query", * @OASchema( * type="array", * @OAItems( type="enum", enum={"drama", "comedy", "thriller"} ), * example={"drama"} * ) * ),
  • 40. Przykład /** * @OAPost( * path="/api/v1/movies", * tags={"movie"}, * @OARequestBody( required=true, @OAJsonContent(ref="#/components/schemas/MovieEdit")), * @OAResponse(response="201", description="director", @OAJsonContent( ref="#/components/schemas/Movie") ) * ) */ public function store(Request $request) { $director = Director::findOrFail($request->director_id); $movie = Movie::create($request->all()); return $movie; } app/Http/Controllers/API/MovieController.php:
  • 42. Przykład /** * @OAGet( * path="/api/v1/movies/{movie_id}", tags={"movie"}, * @OAParameter(name="movie_id", required=true, in="path", @OASchema( type="integer", example=1 ) ), * @OAResponse(response="200", description="director", @OAJsonContent(ref="#/components/schemas/Movie")) * ) */ public function show(Movie $movie) { $movie->director; // load director to movie object return $movie; } app/Http/Controllers/API/MovieController.php:
  • 44. Przykład /** * @OAPut( * path="/api/v1/movies/{movie_id}", * tags={"movie"}, * @OAParameter(name="movie_id", required=true, in="path", @OASchema( type="integer", example=1 ) ), * @OARequestBody( required=true, @OAJsonContent(ref="#/components/schemas/MovieEdit")), * @OAResponse(response="200", description="director", @OAJsonContent( ref="#/components/schemas/Movie") ) * ) */ public function update(Request $request , Movie $movie) { $movie->fill($request ->all())->save(); return $movie; } /** * @OADelete( * path="/api/v1/movies/{movie_id}", tags={"movie"}, * @OAParameter(name="movie_id", required=true, in="path", @OASchema( type="integer", example=1 ) ), * @OAResponse(response="200", description="director", @OAJsonContent(ref="#/components/schemas/MovieEntry")) * ) */ public function destroy(Movie $movie) { $movie->delete(); return $movie; } app/Http/Controllers/API/MovieController.php:
  • 47. Przykład - swagger.json {"openapi":"3.0.0","info":{"title":"Laravel API","description":"My api","version":"0.1"},"paths":{"/api/v1/directors":{"get":{"tags":["director"],"operationId":"AppHttpControllersAPIDirectorController::index","responses":{"200":{"description":"list","content":{"a pplication/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Director"}}}}}}},"post":{"tags":["director"],"operationId":"AppHttpControllersAPIDirectorController::store","re questBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectorEdit"}}}},"responses":{"201":{"description":"director","content":{"application/json":{"sc hema":{"$ref":"#/components/schemas/Director"}}}}}}},"/api/v1/directors/{director_id}":{"get":{"tags":["director"],"operationId":"AppHttpControllersAPIDirectorController::show","parameters": [{"name":"director_id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"director","content":{"application/json":{"schema":{"$ref":"#/compone nts/schemas/Director"}}}}}},"put":{"tags":["director"],"operationId":"AppHttpControllersAPIDirectorController::update","parameters":[{"name":"director_id","in":"path","required":true,"schema ":{"type":"integer","example":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectorEdit"}}}},"responses":{"200":{"description":"direct or","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Director"}}}}}},"delete":{"tags":["director"],"operationId":"AppHttpControllersAPIDirectorController::destroy","para meters":[{"name":"director_id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"director","content":{"application/json":{"schema":{"$ref":"#/c omponents/schemas/Director"}}}}}}},"/api/v1/movies":{"get":{"tags":["movie"],"operationId":"AppHttpControllersAPIMovieController::index","parameters":[{"name":"genre","in":"query","sche ma":{"type":"array","items":{"type":"enum","enum":["drama","comedy","thriller"]},"example":["drama"]}}],"responses":{"200":{"description":"list","content":{"application/json":{"schema":{"type":"arr ay","items":{"$ref":"#/components/schemas/MovieEntry"}}}}}}},"post":{"tags":["movie"],"operationId":"AppHttpControllersAPIMovieController::store","requestBody":{"required":true,"content": {"application/json":{"schema":{"$ref":"#/components/schemas/MovieEdit"}}}},"responses":{"201":{"description":"director","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ Movie"}}}}}}},"/api/v1/movies/{movie_id}":{"get":{"tags":["movie"],"operationId":"AppHttpControllersAPIMovieController::show","parameters":[{"name":"movie_id","in":"path","required":true," schema":{"type":"integer","example":1}}],"responses":{"200":{"description":"director","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Movie"}}}}}},"put":{"tags":["movie"]," operationId":"AppHttpControllersAPIMovieController::update","parameters":[{"name":"movie_id","in":"path","required":true,"schema":{"type":"integer","example":1}}],"requestBody":{"requir ed":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MovieEdit"}}}},"responses":{"200":{"description":"director","content":{"application/json":{"schema":{"$ref":"#/com ponents/schemas/Movie"}}}}}},"delete":{"tags":["movie"],"operationId":"AppHttpControllersAPIMovieController::destroy","parameters":[{"name":"movie_id","in":"path","required":true,"schem a":{"type":"integer","example":1}}],"responses":{"200":{"description":"director","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MovieEntry"}}}}}}},"/test":{"get":{"responses ":{"200":{"description":"x","content":{"application/json":{"schema":{"type":"json"},"example":{"name":"project","items":[5,6,{"a":1,"b":2,"c":[]}]}}}}},"security":[{"oauth2":["*"]}]}}},"components":{"sche mas":{"Director":{"properties":{"id":{"type":"integer","example":3},"first_name":{"type":"string","example":"John"},"last_name":{"type":"string","example":"Smith"},"created_at":{"type":"string","exa mple":"2018-10-21 19:13:37"},"updated_at":{"type":"string","example":"2018-10-31 23:01:34"}},"type":"object"},"DirectorEdit":{"properties":{"first_name":{"$ref":"#/components/schemas/Director/properties/first_name"},"last_name":{"$ref":"#/components/schemas/Director/prop erties/last_name"}},"type":"object"},"Movie":{"properties":{"id":{"type":"integer","example":3},"director":{"$ref":"#/components/schemas/Director"},"title":{"type":"string","example":"Rocky"},"year": {"type":"integer","example":"1976"},"genre":{"type":"enum","enum":["drama","comedy","thriller"],"example":"drama"},"oscar":{"type":"boolean","example":true},"created_at":{"type":"string","exam ple":"2018-10-21 19:13:37"},"updated_at":{"type":"string","example":"2018-10-31 23:01:34"}},"type":"object"},"MovieEntry":{"properties":{"id":{"$ref":"#/components/schemas/Movie/properties/id"},"title":{"$ref":"#/components/schemas/Movie/properties/title"},"year":{"$ref":"#/c omponents/schemas/Movie/properties/year"},"genre":{"$ref":"#/components/schemas/Movie/properties/genre"},"oscar":{"$ref":"#/components/schemas/Movie/properties/oscar"},"created_at":{" $ref":"#/components/schemas/Movie/properties/created_at"},"updated_at":{"$ref":"#/components/schemas/Movie/properties/updated_at"}},"type":"object"},"MovieEdit":{"properties":{"director_id ":{"type":"integer","example":"1"},"title":{"$ref":"#/components/schemas/Movie/properties/title"},"year":{"$ref":"#/components/schemas/Movie/properties/year"},"genre":{"$ref":"#/components/sch emas/Movie/properties/genre"},"oscar":{"$ref":"#/components/schemas/Movie/properties/oscar"}},"type":"object"}},"securitySchemes":{"oauth2":{"type":"oauth2","description":"OAuth2 Password Grant","flows":{"password":{"authorizationUrl":"/oauth/authorize","tokenUrl":"/oauth/token","refreshUrl":"/oauth/token/refresh","scopes":{"*":"ALL scopes"}}}}}}}
  • 48. Podsumowanie Plusy opisywania API za pomocą swaggera w L5: 1. Wersjonowanie opisu (git) 2. Wszystko pod ręką (w kodzie) 3. Publikowanie opisu API bezpośrednio w aplikcji 4. Generyczne UI dla ręcznego testowania API 5. Generowanie swagger JSON/YAML dla innych narzędzi (np. testowania automatycznego, generowania klientów api dla angular etc.) 6. Wsparcie dla oauth2
  • 49. Bonus - Pozycja Krzesło - pomyłka...
  • 50. Bonus - Pozycja Piłka 55cm (~50zł) Prosta pozycja: - zdrowy kręgosłup - głębszy oddech (wydech) - lepsze krążenie - brak nacisku na narz. wew. - więcej energii Prosta pozycja wywoła na początku ból nieprzyzwyczajonych mięśni. Oswajanie się: 1 tydzień - 15 min/dziennie, 2 tydzien - 30 min/dziennie, ... 6 tydzień - 8 godz/dziennie - Wyciągamy czubek głowy by “podnieść nim sufit” - Broda nisko, blisko szyi. - Uszy równo z barkami a nos w linii z pępkiem - Kolana niżej niż biodra - Brzuch blisko krawędzi biurka - Brak oparcia dla pleców, ekran centralnie z przodu - Czubek ekranu na wysokości czubka głowy-wzroku - Piłka mocno napompowana wzorcowo
  • 51. Bonus - Pozycja Piłka - Błędy - za daleko od stołu (powoduje z czasem pochylenie do przodu) - miękka piłka - za nisko ekran - za nisko ekran powoduje z czasem zginanie szyi w dół - ekran z boku - za daleko od stołu - miękka piłka