API Design - OCTO Technology
Transcrição
API Design - OCTO Technology
ProjetodeAPIRESTful–OCTOGuiadeReferênciaRápida Conceitosgerais KISS QualquerumdevesercapazdeusarsuaAPIsemprecisardadocumentação. • Usetermospadrão,concretosecomuns,nuncatermosousiglasdenegócioespecíficosdasuaempresa. • NãodeveexisSrmaisdeumamaneiradeseobterummesmoresultado. • AAPIéprojetadaparaseusclientes(desenvolvedores),nãoparaosseusdados. • Foquenosprincipaiscasosdeuso,edeixeoscasosexcepcionaisparadepois. GET /orders, GET /users, GET /products, etc.! ! CURL ComparSlheváriosexemplosdecURL,quefacilitemousodecopy/paste. CURL –X POST \! -H "Accept: application/json" \ -H "Authorization: Bearer at-80003004-19a8-46a2-908e-33d4057128e7" \ ! -d '{"state":"running"}' \ ! https://api.fakecompany.com/v1/users/007/orders?client_id=API_KEY_003 ! ! URLs GET /orders not /getAllOrders! ! Plurais Usenomesnoplural,enãonosingular,paragerenciardoisSposdiferentesderecursos: • Coleçõesderecursos:/users • Instânciadeumrecurso:/users/007 Considereusaressescincosubdomínios • • • • • ! Consistênciadacaixa Escolhaentresnake_caseoucamelCaseparaatributoseparâmetros,masmantenhaaconsistência ! ! { "id":"007", ! "firstName":"James",! "name":"Bond",! "address":{! "street":"H.Ferry Rd.",! ”city":{"name":"London"}! }! }! APIprodução-https://api.fakecompany.com APIteste-https://api.sandbox.fakecompany.com Developerportal-https://developers.fakecompany.com! OAuth2produção-https://oauth2.fakecompany.com OAuth2 teste - https://oauth2.sandbox.fakecompany.com Segurança:OAuth2&HTTPS VocêdeveusarOAuth2paragerenciaraautorização • OAuth2seencaixaem99%dosrequisitosetopologiasdosclientes,nãoreinventearoda! UseHTTPSparatodasaschamadasdaAPI/OAuth2 GET /users/007 enãoGET /user/007! ouGET /orders?idUser=007! ou POST/orders {"idUser":"007"}! SevocêtemmaisdeumapalavranaURL,usespinal-case(algunsservidoresignoramacaixa) POST /specific-orders! Versionamento UseversionamentoobrigatórionaURL,noescopomaisalto(majorversions) Vocêdevesuportarnomáximoduasversõesaomesmotempo(appsnaSvasprecisamdeumlongociclo) GET /v1/orders! ! Estruturahierárquica LeveahierarquianaturaldosrecursosparaaURLparasugeriraestrutura(agregaçãooucomposição) Ex.:umpedidocontémprodutos ! DELETE Mantenhaaconsistência GET /orders/1234/products/1! Granularidademédiaderecursos Usegranularidademédia,nemfina,nemgrossa Recursosnãodevemseraninhadosemmaisde2níveis: GET /users/007! OperaçõesCRUD:UseverbosHTTPparaoperaçõesCRUD(Create/Read/Update/Delete). VerboHTTP Coleção:/orders Instância:/orders/{id} GET Lêalistadepedidos.200OK. Lêosdetalhesdeumpedidoespecífico.200OK. POST Criaumnovopedido.201Created. - Updatecompleto:200OK./Criaumpedido PUT - específico:201Created. - Updateparcial.200OK. PATCH Nomes Vocêdeveusarnomes(pronomes),nãoverbos(aocontráriodeSOAP-RPC) GET /orders?id_user=007 POST/orders {"id_user":"007"} PARADESENVOLVEDORESEARQUITETOSDEAPI - Deletaumpedido.204OK. POSTéusadoparaCreate(criar)umainstâncianumacoleção.OIDnãoéfornecido,eoendereçodo novorecursoéretornadonoheader“LocaSon”. POST /orders {"state":"running", "id_user":"007"}! 201 Created ! Location: https://api.fakecompany.com/orders/1234! Maslembre-sequeseoIDforfornecidopelocliente,PUTseráusadoparaCreate(criarorecurso). PUT /orders/1234! 201 Created ! ! PUTéusadoparaUpdates,pararealizarumasubsStuiçãocompletadorecurso. PUT /orders/1234 {"state":"paid", "id_user":"007"}! 200 Ok! PATCHéfrequentementeusadoparaUpdatesparciais,subsStuindoalgunsatributos. PATCH /orders/1234 {"state":"paid"}! 200 Ok! GETéusadoparaRead(ler)acoleção. GETéusadoparaRead(ler)umainstância. GET /orders ! ! 200 Ok ! ! [{"id":"1234", "state":"paid"} {"id":"5678", "state":"running"}]! GET /orders/1234! 200 Ok! {"id":"1234", "state":"paid"}! ! ©2015OCTOTechnology ! www.octo.com/pt-br Page1 ProjetodeAPIRESTful–OCTOGuiadeReferênciaRápida Querystrings Outrosconceitosimportantes Busca Vocêpodeusaro“Googleway”parafazerumabuscaglobalemmúlSplosrecursos. GET /search?q=running+paid! Filtros Use‘?’parafiltrarrecursos GET /orders?state=payed&id_user=007! ou(múlSplasURIspodemreferenciaromesmorecurso) GET /users/007/orders?state=paied! ! Paginação Vocêpodeusarumparâmetrorange(faixadevalores)naquery.Apaginaçãoéobrigatória:uma paginaçãodefaulttemqueserdefinida,porexemplo:range=0-25. Oresponsedeveconterosheaders:Link,Content-Range,Accept-Range. Notequeapaginaçãopodecausarcomportamentoestranhosemuitosrecursosforemadicionados. /orders?range=48-55! 206 Partial Content! Content-Range: 48-55/971! Accept-Range: order 10! Link : <https://api.fakecompany.com/v1/orders?range=0-7>; rel="first", ! <https://api.fakecompany.com/v1/orders?range=40-47>; rel="prev", ! <https://api.fakecompany.com/v1/orders?range=56-64>; rel="next", ! <https://api.fakecompany.com/v1/orders?range=968-975>; rel="last"! ! Responsesparciais UseparSalresponsesparaqueosdesenvolvedorespossamescolherqualinformaçãoelesprecisam, paraoSmizarbanda(fundamentalparadesenvolvimentomobile). GET /users/007?fields=firstname,name,address(street)! 200 OK! { "id":"007", ! "firstname":"James",! "name":"Bond",! address:{"street":"Horsen Ferry Road"}! }! GET /restaurants?sort=rating,reviews,name;desc=rate,reviews! ! PalavrasreservadasnaURL:first,last,count Use/firstparaobtero1ºelemento Use/lastparaobteroúlSmorecursodeumacoleção !GET /orders/last! !200 OK! !{"id":"5678", "state":"running"} ! Use/countparaobterotamanhoatualdacoleção GET /orders/count !! 200 OK ! {"2"} ! ©2015OCTOTechnology Negociaçãodeconteúdo AnegociaçãodeconteúdoéconduzidasomentedaformaRESTfulpura.OsclientesrequisitamoSpodo conteúdo,noheaderAccept,naordemdepreferência.OformatodefaultéJSON. Accept: application/json, text/plain enão /orders.json! ! I18N(internacionalização) UseopadrãoISO8601paraDate/Time/Timestamp:1978-05-10T06:06:06+00:00ou1978-05-10! Adicionesuporteparaoutraslinguas. Accept-Language: fr-CA, fr-FR enão ?language=fr! ! Requisiçõescross-origin UseopadrãoCORSparasuportarrequisiçõesdebrowsersparaaAPIREST(jsSPA,etc.). MassevocêvaisuportarInternetExplorer7/8/9,vocêdeveconsiderarendpointsespecíficospara adicionarsuporteJSONP. • TodososrequestsserãoenviadoscommétodoGET! • AnegociaçãodeconteúdonãopodeserfeitanoheaderAcceptcomJSONP. • Opayloadnãopodeserusadoparaenviardados. ! POST /orders GET /orders GET /orders/1234 PUT /orders/1234 etambém etambém etambém etambém /orders.jsonp?method=POST&callback=foo! /orders.jsonp?callback=foo! /orders/1234.jsonp?callback=foo! /orders/1234.jsonp?method=PUT&callback=foo! Atenção:umwebcrawlerpodefacilmentecausarproblemasnasuaaplicaçãocomumparâmetro method.CerSfique-sedepedirsempreumaccess_tokenOAuth2,etambémoclient_idOAuth2. HATEOAS SuaAPIdeveoferecerlinksHypermediaparasertotalmentediscoverable.Mastenhaemmentequea maioriadosusuáriosnãovãousaresseshyperlinksporenquanto,evãoprecisardadocumentaçãodaAPI edefazercopy/pastecomosexemplosdechamadas. Então,cadachamadaparaaAPIdeveretornarnoheaderLinktodosospossíveisestadosdaaplicaçãoa parSrdoestadoatual,alémdelemesmo. VocêpodeusaranotaçãodeLinkdaRFC5988paraimplementaroHATEOAS: GET /users/007! < 200 Ok! < { "id":"007", "firstname":"James",...}! < Link : <https://api.fakecompany.com/v1/users>; rel="self"; method:"GET",! <https://api.fakecompany.com/v1/addresses/42>; rel="addresses"; method:"GET",! <https://api.fakecompany.com/v1/orders/1234>; rel="orders"; method:"GET"! Ordenação Use?sort=atribute1,atributeNparaordenarrecursos.Aordenaçãocrescenteédefault. Use?desc=atribute1,atributeNparaordenaremordemdecrescente. GET /orders/first ! 200 OK ! {"id":"1234", "state":"paid"} PARADESENVOLVEDORESEARQUITETOSDEAPI Cenários“Semrecursos” Emalgunspoucoscasosprecisamosconsideraroperaçõesouserviçosaoinvésderecursos. VocêpodeusarumrequestPOSTcomumverbonofinaldaURI POST /emails/42/send! POST /calculator/sum [1,2,3,5,8,13,21]! POST /convert?from=EUR&to=USD&amount=42! ! MasvocêdeveconsiderarusarrecursosRESTfulantesdeparSrparaumasoluçãocomverbos. www.octo.com/pt-br Page2 ProjetodeAPIRESTful–OCTOGuiadeReferênciaRápida PARADESENVOLVEDORESEARQUITETOSDEAPI StatuscodesHTTP VocêdeveusarstatuscodesHTTPadequados. VocêpodeusaranotaçãopadrãoOAuth2:hyp://tools.iez.org/html/rfc6749#page-45 Mantenhaasimplicidade:nãotenteusartodososstatuscodesHTTP,masapenasos12principais. VerboHTTP StatuscodeHTTP Descrição 200OK. Códigodesucessobásico.Funcionaparanamaioriadoscasos.EspecialmenteusadonosucessodoprimeirorequestGET,ouupdatecomPUT/PATCH. 201Created. Indicaqueorecursofoicriado.Resposta|picaaumrequestPUTouPOST. SUCCESS 202Accepted. Indicaqueorequestfoiaceitoparaprocessamento.Resposta|picaaumachamadaparaprocessamentoassíncrono(paramelhorUXeboaperformance). 204NoContent. Orequestfuncionou,masnãoháconteúdoaretornar.RespostacomumparaumDELETEcomsucesso. 206ParSalContent. Orecursoretornadoestáincompleto.Usadonormalmenteemrecursospaginados. Errogeralparaqualquerrequest(casonãoseencaixenosdemais).AboapráScaéterdoisSposdeerros:erronorequest,econdiçãodeerronaaplicação. Exemplodeerronorequest: GET/users?payed=1 <400BadRequest 400Badrequest. <{"error":"invalid_request","error_descripSon":“Thereisno‘payed'propertyonusers."} Exemplodecondiçãodeerronaaplicação: POST/users {"name":"JohnDoe”} <400BadRequest <{"error":"invalid_user","error_descripSon":"Ausermusthaveanemailadress"}! Eunãoconheçooseuid.Diga-mequemvocêé,eeuvejosuaautorização. GET/users/42/orders 401Unauthorized. <401Unauthorized <{"error":"no_credenSals","error_descripSon":"Thisresourceisunderpermission,youmustbeauthenScatedwiththerightrightstohaveaccesstoit"}! VocêfoiautenScadocorretamente,masnãotemprivilégiossuficientes. CLIENTERROR GET/users/42/orders 403Forbidden. <403Forbidden <{"error":"not_allowed","error_descripSon":"You’renotallowedtoperformthisrequest"}! Orecursoquevocêpediunãoexiste. GET/users/999999 404NotFound. <400NotFound <{"error":"not_found","error_descripSon":"Theuserwiththeid‘999999’doesn’texist"}! VocêchamouummétodoquenãofazsenSdonesserecurso,ouousuárionãotempermissãodefazeressachamada. POST/users/8000 405Methodnotallowed. <405MethodNotAllowed <{"error":"method_does_not_make_sense","error_descripSon":"Howwouldyouevenpostaperson?"}! NenhumformatoseencaixanoHeaderAccept-*doseurequest.Porexemplo,vocêpediuorecursoemformatoXML,maselesóestádisponívelemJSON.Isso tambémfuncionaparaI18N(internacionalização). GET/users 406NotAcceptable. Accept:text/xml Accept-Language:fr-fr <406NotAcceptable <Content-Type:applicaSon/json <{"error":"not_acceptable","available_languages":["us-en","de","kr-ko"]}! Arequisiçãoestácorreta,masocorreuumerrodeexecução.Oclientenãotemmuitooquefazersobreisso,entãoapenasretorneumstatus500. SERVERERROR ©2015OCTOTechnology GET/users 500InternalserverError. <500Internalservererror <Content-Type:applicaSon/json <{"error":"server_error","error_descripSon":"Oops!Somethingwentwrong..."} www.octo.com/pt-br Page3 ProjetodeAPIRESTful–OCTOGuiadeReferênciaRápida PARADESENVOLVEDORESEARQUITETOSDEAPI AVISO EsseGuiadeReferêncianãopretendesertotalmentepreciso.Osconceitosde projetoaquiexpostossãoresultadodeprojetosanteriorescomREST.Leianosso bloghyp://blog.octo.com/pt-br,esinta-seàvontadeparacomentar/desafiaresse guiadeAPIs.NósesperamospodercomparSlharmaisexperiênciascomvocê. Maisumacoisa NósoencorajamosaserpragmáSco,paraobene‰ciodosseusclientes: Desenvolvedoresdeaplica/vos. Fontes DesignBeauSfulREST+JSONAPIs >hyp://www.slideshare.net/stormpath/rest-jsonapis WebAPIDesign:Cra•ingInterfacesthatDevelopersLove >hyps://pages.apigee.com/web-api-design-website-h-ebook-registraSon.html HTTPAPIDesignGuide >hyps://github.com/interagent/hyp-api-design RESTfulWebAPIs >hyp://shop.oreilly.com/product/0636920028468.do ©2015OCTOTechnology www.octo.com/pt-br Page4