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

FDD - HR & SSHR - V2.2.docx
FDD - HR & SSHR - V2.2.docxFDD - HR & SSHR - V2.2.docx
FDD - HR & SSHR - V2.2.docxZeeshan Ikram
 
The Path Towards Spring Boot Native Applications
The Path Towards Spring Boot Native ApplicationsThe Path Towards Spring Boot Native Applications
The Path Towards Spring Boot Native ApplicationsVMware Tanzu
 
Online bus booking system-A Case study on Normalisation
Online bus booking system-A Case study on NormalisationOnline bus booking system-A Case study on Normalisation
Online bus booking system-A Case study on NormalisationSavita Marwal
 
AWS 관리형 서비스를 중심으로 한 NCSOFT 와 Reality Reflection의 클라우드 사용기 - AWS Summit Seoul ...
AWS 관리형 서비스를 중심으로 한 NCSOFT 와 Reality Reflection의 클라우드 사용기 - AWS Summit Seoul ...AWS 관리형 서비스를 중심으로 한 NCSOFT 와 Reality Reflection의 클라우드 사용기 - AWS Summit Seoul ...
AWS 관리형 서비스를 중심으로 한 NCSOFT 와 Reality Reflection의 클라우드 사용기 - AWS Summit Seoul ...Amazon Web Services Korea
 
Fujcci oracle hr user_manual
Fujcci oracle hr user_manualFujcci oracle hr user_manual
Fujcci oracle hr user_manualFeras Ahmad
 
Understanding REST APIs in 5 Simple Steps
Understanding REST APIs in 5 Simple StepsUnderstanding REST APIs in 5 Simple Steps
Understanding REST APIs in 5 Simple StepsTessa Mero
 
How to Create Oracle Fusion BI Publisher Report Using RTF Template
How to Create Oracle Fusion BI Publisher Report Using RTF TemplateHow to Create Oracle Fusion BI Publisher Report Using RTF Template
How to Create Oracle Fusion BI Publisher Report Using RTF TemplateFeras Ahmad
 
Sap implementation
Sap implementationSap implementation
Sap implementationsydraza786
 
iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術Yuji Hato
 
LetsSwift(강민규스피커,안정민서포터).pptx
LetsSwift(강민규스피커,안정민서포터).pptxLetsSwift(강민규스피커,안정민서포터).pptx
LetsSwift(강민규스피커,안정민서포터).pptxssuser2601f7
 
SAP BASIS Practice Exam
SAP BASIS Practice ExamSAP BASIS Practice Exam
SAP BASIS Practice ExamIT LearnMore
 

What's hot (20)

Rest api and-crud-api
Rest api and-crud-apiRest api and-crud-api
Rest api and-crud-api
 
flask.pptx
flask.pptxflask.pptx
flask.pptx
 
SAP HANA on Red Hat
SAP HANA on Red HatSAP HANA on Red Hat
SAP HANA on Red Hat
 
FDD - HR & SSHR - V2.2.docx
FDD - HR & SSHR - V2.2.docxFDD - HR & SSHR - V2.2.docx
FDD - HR & SSHR - V2.2.docx
 
The Path Towards Spring Boot Native Applications
The Path Towards Spring Boot Native ApplicationsThe Path Towards Spring Boot Native Applications
The Path Towards Spring Boot Native Applications
 
Online bus booking system-A Case study on Normalisation
Online bus booking system-A Case study on NormalisationOnline bus booking system-A Case study on Normalisation
Online bus booking system-A Case study on Normalisation
 
AWS 관리형 서비스를 중심으로 한 NCSOFT 와 Reality Reflection의 클라우드 사용기 - AWS Summit Seoul ...
AWS 관리형 서비스를 중심으로 한 NCSOFT 와 Reality Reflection의 클라우드 사용기 - AWS Summit Seoul ...AWS 관리형 서비스를 중심으로 한 NCSOFT 와 Reality Reflection의 클라우드 사용기 - AWS Summit Seoul ...
AWS 관리형 서비스를 중심으로 한 NCSOFT 와 Reality Reflection의 클라우드 사용기 - AWS Summit Seoul ...
 
Fujcci oracle hr user_manual
Fujcci oracle hr user_manualFujcci oracle hr user_manual
Fujcci oracle hr user_manual
 
Understanding REST APIs in 5 Simple Steps
Understanding REST APIs in 5 Simple StepsUnderstanding REST APIs in 5 Simple Steps
Understanding REST APIs in 5 Simple Steps
 
How to Create Oracle Fusion BI Publisher Report Using RTF Template
How to Create Oracle Fusion BI Publisher Report Using RTF TemplateHow to Create Oracle Fusion BI Publisher Report Using RTF Template
How to Create Oracle Fusion BI Publisher Report Using RTF Template
 
Sap implementation
Sap implementationSap implementation
Sap implementation
 
Angular material
Angular materialAngular material
Angular material
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
 
Xke spring boot
Xke spring bootXke spring boot
Xke spring boot
 
react redux.pdf
react redux.pdfreact redux.pdf
react redux.pdf
 
iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術
 
LetsSwift(강민규스피커,안정민서포터).pptx
LetsSwift(강민규스피커,안정민서포터).pptxLetsSwift(강민규스피커,안정민서포터).pptx
LetsSwift(강민규스피커,안정민서포터).pptx
 
RESTful API - Best Practices
RESTful API - Best PracticesRESTful API - Best Practices
RESTful API - Best Practices
 
Angular Basics.pptx
Angular Basics.pptxAngular Basics.pptx
Angular Basics.pptx
 
SAP BASIS Practice Exam
SAP BASIS Practice ExamSAP BASIS Practice Exam
SAP BASIS Practice Exam
 

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
 
xD bug - Jak debugować PHP-owe aplikacje (Xdebug)
xD bug - Jak debugować PHP-owe aplikacje (Xdebug) xD bug - Jak debugować PHP-owe aplikacje (Xdebug)
xD bug - Jak debugować PHP-owe aplikacje (Xdebug) 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
 

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...
 
xD bug - Jak debugować PHP-owe aplikacje (Xdebug)
xD bug - Jak debugować PHP-owe aplikacje (Xdebug) xD bug - Jak debugować PHP-owe aplikacje (Xdebug)
xD bug - Jak debugować PHP-owe aplikacje (Xdebug)
 
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
 

Recently uploaded

Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
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
 
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
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
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
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
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
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
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
 

Recently uploaded (20)

Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
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
 
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
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
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...
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
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...
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
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
 
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
 

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