{"id":2069,"date":"2021-06-09T19:53:15","date_gmt":"2021-06-09T22:53:15","guid":{"rendered":"https:\/\/elemarjr.com\/arquiteturadesoftware\/?p=2069"},"modified":"2024-01-16T15:04:45","modified_gmt":"2024-01-16T18:04:45","slug":"solucoes-faceis-para-problemas-dificeis-rest","status":"publish","type":"volume-1","link":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/","title":{"rendered":"AP-A Solu\u00e7\u00f5es f\u00e1ceis para problemas dif\u00edceis REST"},"content":{"rendered":"<p>Implementar solu\u00e7\u00f5es RESTful nem sempre \u00e9 tarefa trivial. Neste ap\u00eandice, apresentamos algumas solu\u00e7\u00f5es para desafios comuns.<\/p>\n<h2>Suportando opera\u00e7\u00f5es com longa dura\u00e7\u00e3o<\/h2>\n<p>HTTP \u00e9 um protocolo s\u00edncrono e\u00a0<em>stateless.\u00a0<\/em>Sempre que uma requisi\u00e7\u00e3o \u00e9 submetida a um &#8220;componente servidor&#8221;, \u00a0\u00e9 normal que o &#8220;componente cliente&#8221; espere por uma resposta indicando falha ou sucesso. Entretanto, nem sempre \u00e9 poss\u00edvel executar todo o processamento em tempo razo\u00e1vel.<\/p>\n<h4>Opera\u00e7\u00f5es de longa dura\u00e7\u00e3o iniciadas por HTTP POST<\/h4>\n<p><strong><em>Problema<\/em><\/strong><\/p>\n<p>Eventualmente, opera\u00e7\u00f5es iniciadas com verbos HTTP POST demoram para serem completadas. Logo, se implementadas ingenuamente, &#8220;seguram&#8221; o componentes &#8220;cliente&#8221; por muito tempo, eventualmente com\u00a0<em>timeout.<\/em><\/p>\n<p><em><strong>Solu\u00e7\u00e3o<\/strong><\/em><\/p>\n<p>Ao executar opera\u00e7\u00f5es de longa dura\u00e7\u00e3o, iniciadas por verbos HTTP POST, o componente &#8220;servidor&#8221; deve retornar rapidamente uma\u00a0<em>response\u00a0<\/em>marcada com c\u00f3digo HTTP 202 (<em>Accepted<\/em>) e com uma representa\u00e7\u00e3o de um recurso espec\u00edfico para indicar o andamento.<\/p>\n<pre>HTTP\/1.1 202 Accepted\r\nContent-Type: application\/json; charset=UTF-8\r\nContent-Location: \/tasks\/1\r\nDate: ...\r\n\r\n{\r\n  status: \"accepted\",\r\n  message: \"Your request has been accepted for processing.\",\r\n  ping-after: ... \r\n  links: [\r\n  {\r\n    rel: \"self\",\r\n    href: \"\/tasks\/1\"\r\n  }\r\n  ]\r\n}\r\n<\/pre>\n<p>\u00c9 importante que este recurso possua, al\u00e9m de um indicador de\u00a0<em>status\u00a0<\/em>uma &#8220;previs\u00e3o&#8221; de quanto tempo a opera\u00e7\u00e3o dever\u00e1 consumir.<\/p>\n<p>Solicita\u00e7\u00f5es HTTP GET futuras para o recurso indicado na URL<em>\u00a0<\/em>de acompanhamento devem ser ajustadas conforme estado de processamento:<\/p>\n<ul>\n<li>se o processamento ainda n\u00e3o tiver sido completado, o recurso deve indicar\u00a0<i>status &#8220;still\u00a0Processing&#8221;,\u00a0<\/i>retornando 200 (<em>OK<\/em>). Al\u00e9m disso, \u00e9 recomend\u00e1vel ajustar o <em>caching <\/em>considerando tempo de processamento, aliviando press\u00e3o sobre o componente &#8220;servidor&#8221;<\/li>\n<li>se o processamento foi completado com \u00eaxito, retornar 303 (<i>Ser Other<\/i>) com\u00a0<em>Location\u00a0<\/em>indicando URL do recurso gerado.<\/li>\n<li>se o processamento n\u00e3o foi completado com \u00eaxito, retornar 200 (<em>OK<\/em>) com documento de <em>status\u00a0<\/em>indicando a falha que ocorreu.<\/li>\n<\/ul>\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 30px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Montserrat;\">HTTP n\u00e3o foi pensado para ser ass\u00edncrono<\/p>\r\n<\/p>\n<p>Um detalhe que pode chamar a aten\u00e7\u00e3o na solu\u00e7\u00e3o proposta \u00e9 o retorno de 200 (<em>OK<\/em>), para recuperar o recurso de estado quando h\u00e1 falha no processamento. O motivo para isso \u00e9 que a recupera\u00e7\u00e3o do recurso com o <em>status<\/em>, em si, n\u00e3o falhou.<\/p>\n<p><\/div>\n<h4>Opera\u00e7\u00f5es de longa dura\u00e7\u00e3o iniciadas por HTTP POST e DELETE<\/h4>\n<p><strong><em>Problema<\/em><\/strong><\/p>\n<p>Eventualmente, opera\u00e7\u00f5es iniciadas com verbos HTTP PUT e DELETE demoram para serem completadas. Logo, se implementadas ingenuamente, &#8220;seguram&#8221; o componentes &#8220;cliente&#8221; por muito tempo, eventualmente com\u00a0<em>timeout.<\/em><\/p>\n<p><em><strong>Solu\u00e7\u00e3o<\/strong><\/em><\/p>\n<p>Ao executar opera\u00e7\u00f5es de longa dura\u00e7\u00e3o, iniciadas por verbos HTTP DELETE, o componente &#8220;servidor&#8221; deve retornar rapidamente uma\u00a0<em>response\u00a0<\/em>marcada com c\u00f3digo HTTP 202 (<em>Accepted<\/em>) e com uma representa\u00e7\u00e3o de um recurso espec\u00edfico para indicar o andamento, de forma quase id\u00eantica a abordagem para suportar opera\u00e7\u00f5es HTTP POST &#8211; a mudan\u00e7a \u00e9 n\u00e3o fazer redirecionamento ao concluir a opera\u00e7\u00e3o (opcionalmente, para opera\u00e7\u00f5es PUT)<\/p>\n<h2>Requisi\u00e7\u00f5es condicionais (<em>caching<\/em>)<\/h2>\n<p>Opera\u00e7\u00f5es HTTP GET n\u00e3o suportadas por\u00a0<em>caching\u00a0<\/em>podem comprometer a performance de uma API em produ\u00e7\u00e3o. A utiliza\u00e7\u00e3o inadequada de <em>caching\u00a0<\/em>pode causar problemas s\u00e9rios de consist\u00eancia em opera\u00e7\u00f5es PUT, POST e DELETE (n\u00e3o seguras).<\/p>\n<p>Toda vez que um componente &#8220;cliente&#8221; utilizar mecanismos de\u00a0<em>caching\u00a0<\/em>local, afim de reduzir a quantidade de requisi\u00e7\u00f5es custosas para um componente &#8220;servidor&#8221; para melhorar a performance, dever\u00e1 armazenar, tamb\u00e9m, no\u00a0<em>cache\u00a0<\/em>as informa\u00e7\u00f5es <em>Last-Modified\u00a0<\/em>e <em>ETag.<\/em><\/p>\n<h4>Gest\u00e3o de concorr\u00eancia<\/h4>\n<p>Assuma o seguinte fluxo:<\/p>\n<ol>\n<li>Dois usu\u00e1rios, em duas m\u00e1quinas separadas, acessam o &#8220;cadastro&#8221; de um mesmo cliente (HTTP GET)<\/li>\n<li>Os dois usu\u00e1rios alteram em &#8220;campos&#8221; diferentes<\/li>\n<li>Um dos usu\u00e1rios, submete atualiza\u00e7\u00e3o dos dados do cliente (por exemplo, usando HTTP PUT), mudando uma representa\u00e7\u00e3o do recurso, pedindo atualiza\u00e7\u00e3o de estado no componente &#8220;servidor&#8221;<\/li>\n<li>O segundo usu\u00e1rio, logo depois, tamb\u00e9m submete atualiza\u00e7\u00e3o de dados.<\/li>\n<\/ol>\n<hr \/>\n<p>Como impedir, no fluxo, que o segundo usu\u00e1rio n\u00e3o &#8220;mate&#8221; as altera\u00e7\u00f5es do primeiro? Este problema \u00e9 reconhecido, em TI, como gest\u00e3o de concorr\u00eancia. H\u00e1 duas abordagens comuns:<\/p>\n<ol>\n<li>concorr\u00eancia pessimista &#8211; onde um usu\u00e1rio, ao obter dados para altera\u00e7\u00e3o, &#8220;bloqueia&#8221; o acesso ao recurso para outros fluxos de altera\u00e7\u00e3o concorrentes at\u00e9 que as modifica\u00e7\u00f5es estejam efetivadas.<\/li>\n<li>concorr\u00eancia otimista &#8211; onde sempre que um componente &#8220;cliente&#8221; recupera o estado de um recurso, obt\u00e9m junto um\u00a0<em>token\u00a0<\/em>de versionamento (que \u00e9 modificado sempre que o recurso tem estado atualizado no componente &#8220;servidor&#8221;). Dessa forma, sempre que uma tentativa de atualiza\u00e7\u00e3o \u00e9 realizada, o\u00a0<em>token\u00a0<\/em>de versionamento que foi obtido no GET \u00e9 enviado junto no <em>request <\/em>(opera\u00e7\u00f5es PUT, POST ou DELETE),\u00a0sendo que, se j\u00e1 n\u00e3o for mais o <em>token\u00a0<\/em>vigente, a opera\u00e7\u00e3o falha.<\/li>\n<\/ol>\n<hr \/>\n<p>Por causa da restri\u00e7\u00e3o de que servi\u00e7os REST devem ser <em>stateless<\/em>, apenas a abordagem otimista \u00e9 considerada v\u00e1lida.<\/p>\n<h4>Estabelecendo <em>tokens<\/em> de versionamento<\/h4>\n<p>Em HTTP h\u00e1 duas abordagens comuns para associa\u00e7\u00e3o de\u00a0<em>tokens\u00a0<\/em>de versionamento de recursos:<\/p>\n<ol>\n<li>Atributo de cabe\u00e7alho <em>Last-Modified\u00a0&#8211;\u00a0<\/em>explicitando quando aconteceu a \u00faltima modifica\u00e7\u00e3o (em hor\u00e1rio do servidor)<\/li>\n<li>Atributo de cabe\u00e7alho <em>ETag\u00a0<\/em>&#8211; com uma &#8220;chave de conte\u00fado&#8221;, geralmente <em>hash\u00a0<\/em>ou vers\u00e3o.<\/li>\n<\/ol>\n<hr \/>\n<p>Essas\u00a0<em>tokens\u00a0<\/em>podem ser determinadas seguindo uma das seguintes abordagens:<\/p>\n<ol>\n<li>Caso seja poss\u00edvel armazenar, junto as informa\u00e7\u00f5es de recurso, a data da \u00faltima modifica\u00e7\u00e3o ou um n\u00famero de vers\u00e3o (por exemplo, em uma coluna no banco de dados), estes valores poder\u00e3o ser utilizados, tamb\u00e9m, para\u00a0<em>Last-Modified\u00a0<\/em>e\u00a0<em>ETag.<\/em><\/li>\n<li>Se o recurso n\u00e3o for grande ou custoso de ser obtido, poder\u00e1 ter uma <em>hash<\/em>\u00a0(por exemplo MD5) computada\u00a0<em>on-the-fly\u00a0<\/em>sempre que necess\u00e1rio.<\/li>\n<li>Se o recurso for grande ou custoso de ser obtido, a\u00a0<em>hash\u00a0<\/em>poder\u00e1 ser gerada sempre que o estado do recurso for modificado e armazenada<\/li>\n<\/ol>\n<hr \/>\n<h4>Opera\u00e7\u00f5es com GET ou HEAD condicional<\/h4>\n<p>Requisi\u00e7\u00f5es para a URL de um recurso armazenado no <em>cache\u00a0<\/em>devem conter os valores de\u00a0<em>If-Modified-Since<\/em>\u00a0e\u00a0<em>If-None-Match\u00a0<\/em>ajustados com, respectivamente, os valores de\u00a0<em>Last-Modified\u00a0<\/em>e\u00a0<em>ETag<\/em> da \u00faltima requisi\u00e7\u00e3o.<\/p>\n<p>Sempre que um componente &#8220;servidor&#8221; receber uma requisi\u00e7\u00e3o HTTP GET com valores em\u00a0<em>If-Modified-Since\u00a0<\/em>e\u00a0<em>If-None-Match\u00a0<\/em>dever\u00e1 compar\u00e1-los com os valores vigentes e, se permanecerem iguais, retornar 304 (<em>Not Modified<\/em>), sinalizando para o &#8220;cliente&#8221; que os valores em\u00a0<em>cache\u00a0<\/em>permanecem v\u00e1lidos. Caso contr\u00e1rio, uma nova representa\u00e7\u00e3o do recurso dever\u00e1 ser retornada com o c\u00f3digo 200 (<em>Ok<\/em>)<\/p>\n<h4>Opera\u00e7\u00f5es com PUT ou DELETE \u00a0condicional<\/h4>\n<p>Atualiza\u00e7\u00f5es em recursos em que \u00e9 necess\u00e1rio manter gest\u00e3o de concorr\u00eancia otimista devem conter\u00a0os valores de\u00a0<em>If-Unmodified-Since<\/em>\u00a0e\u00a0<em>If-Match\u00a0<\/em>ajustados com, respectivamente, os valores de\u00a0<em>Last-Modified\u00a0<\/em>e\u00a0<em>ETag<\/em> da \u00faltima requisi\u00e7\u00e3o.<\/p>\n<p>Requisi\u00e7\u00f5es PUT ou DELETE \u00a0para recursos que tem gest\u00e3o de concorr\u00eancia otimista:<\/p>\n<ul>\n<li>que n\u00e3o tenham valores definidos para <em>If-Unmodified-Since<\/em>\u00a0e\u00a0<em>If-Match,\u00a0<\/em>devem ser &#8220;negadas&#8221; pelo servidor retornando 403 (<em>Forbidden<\/em>).<\/li>\n<li>que tenham\u00a0<em>tokens\u00a0<\/em>de versionamento desatualizados, devem ser &#8220;negadas&#8221; pelo servidor retornando 412 (<em>Pre condition failed<\/em>)<\/li>\n<li>que tenham <em>tokens\u00a0<\/em>de versionamento atualizados, devem ser &#8220;aceitas&#8221; pelo servidor, retornando 200\u00a0<em>(OK<\/em>) ou\u00a0<em>204\u00a0<\/em>(<em>No Content),\u00a0<\/em>junto com, para requisi\u00e7\u00f5es PUT, atualiza\u00e7\u00f5es para\u00a0<em>Last-Modified\u00a0<\/em>e\u00a0<em>ETag<\/em><\/li>\n<\/ul>\n<hr \/>\n<p>Sempre que um componente &#8220;servidor&#8221; receber uma requisi\u00e7\u00e3o HTTP GET com valores em\u00a0<em>If-Modified-Since\u00a0<\/em>e\u00a0<em>If-None-Match\u00a0<\/em>dever\u00e1 compar\u00e1-los com os valores vigentes e, se permanecerem iguais, retornar 304 (<em>Not Modified<\/em>), sinalizando para o &#8220;cliente&#8221; que os valores em\u00a0<em>cache\u00a0<\/em>permanecem v\u00e1lidos. Caso contr\u00e1rio, uma nova representa\u00e7\u00e3o do recurso dever\u00e1 ser retornada com o c\u00f3digo 200 (<em>Ok<\/em>).<\/p>\n","protected":false},"featured_media":2085,"parent":0,"comment_status":"open","ping_status":"closed","template":"","url":[72],"sessoes":[73],"apendices":[42],"capitulos":[],"class_list":["post-2069","volume-1","type-volume-1","status-publish","has-post-thumbnail","hentry","url-permanente","sessoes-x-apendice","apendices-apendice-a"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>AP-A Solu\u00e7\u00f5es f\u00e1ceis para problemas dif\u00edceis REST - Manual do Arquiteto de Software<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"AP-A Solu\u00e7\u00f5es f\u00e1ceis para problemas dif\u00edceis REST - Manual do Arquiteto de Software\" \/>\n<meta property=\"og:description\" content=\"Implementar solu\u00e7\u00f5es RESTful nem sempre \u00e9 tarefa trivial. Neste ap\u00eandice, apresentamos algumas solu\u00e7\u00f5es para desafios comuns. Suportando opera\u00e7\u00f5es com longa dura\u00e7\u00e3o HTTP \u00e9 um protocolo s\u00edncrono e\u00a0stateless.\u00a0Sempre que uma requisi\u00e7\u00e3o \u00e9 submetida a um &#8220;componente servidor&#8221;, \u00a0\u00e9 normal que o &#8220;componente cliente&#8221; espere por uma resposta indicando falha ou sucesso. Entretanto, nem sempre \u00e9 poss\u00edvel [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/\" \/>\n<meta property=\"og:site_name\" content=\"Manual do Arquiteto de Software\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/facebook.com\/eximiaco\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-16T18:04:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/hello-i-m-nik-LUYD2b7MNrg-unsplash.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"683\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@eximiaco\" \/>\n<meta name=\"twitter:label1\" content=\"Est. tempo de leitura\" \/>\n\t<meta name=\"twitter:data1\" content=\"6 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/\",\"name\":\"AP-A Solu\u00e7\u00f5es f\u00e1ceis para problemas dif\u00edceis REST - Manual do Arquiteto de Software\",\"isPartOf\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/hello-i-m-nik-LUYD2b7MNrg-unsplash.jpg\",\"datePublished\":\"2021-06-09T22:53:15+00:00\",\"dateModified\":\"2024-01-16T18:04:45+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/#primaryimage\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/hello-i-m-nik-LUYD2b7MNrg-unsplash.jpg\",\"contentUrl\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/hello-i-m-nik-LUYD2b7MNrg-unsplash.jpg\",\"width\":1024,\"height\":683},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Volume 1\",\"item\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"AP-A Solu\u00e7\u00f5es f\u00e1ceis para problemas dif\u00edceis REST\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/\",\"name\":\"Manual do Arquiteto de Software\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization\",\"name\":\"EximiaCo\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg\",\"contentUrl\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg\",\"width\":150,\"height\":150,\"caption\":\"EximiaCo\"},\"image\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/facebook.com\/eximiaco\",\"https:\/\/x.com\/eximiaco\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"AP-A Solu\u00e7\u00f5es f\u00e1ceis para problemas dif\u00edceis REST - Manual do Arquiteto de Software","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/","og_locale":"pt_BR","og_type":"article","og_title":"AP-A Solu\u00e7\u00f5es f\u00e1ceis para problemas dif\u00edceis REST - Manual do Arquiteto de Software","og_description":"Implementar solu\u00e7\u00f5es RESTful nem sempre \u00e9 tarefa trivial. Neste ap\u00eandice, apresentamos algumas solu\u00e7\u00f5es para desafios comuns. Suportando opera\u00e7\u00f5es com longa dura\u00e7\u00e3o HTTP \u00e9 um protocolo s\u00edncrono e\u00a0stateless.\u00a0Sempre que uma requisi\u00e7\u00e3o \u00e9 submetida a um &#8220;componente servidor&#8221;, \u00a0\u00e9 normal que o &#8220;componente cliente&#8221; espere por uma resposta indicando falha ou sucesso. Entretanto, nem sempre \u00e9 poss\u00edvel [&hellip;]","og_url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/","og_site_name":"Manual do Arquiteto de Software","article_publisher":"https:\/\/facebook.com\/eximiaco","article_modified_time":"2024-01-16T18:04:45+00:00","og_image":[{"width":1024,"height":683,"url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/hello-i-m-nik-LUYD2b7MNrg-unsplash.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_site":"@eximiaco","twitter_misc":{"Est. tempo de leitura":"6 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/","name":"AP-A Solu\u00e7\u00f5es f\u00e1ceis para problemas dif\u00edceis REST - Manual do Arquiteto de Software","isPartOf":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website"},"primaryImageOfPage":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/#primaryimage"},"image":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/#primaryimage"},"thumbnailUrl":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/hello-i-m-nik-LUYD2b7MNrg-unsplash.jpg","datePublished":"2021-06-09T22:53:15+00:00","dateModified":"2024-01-16T18:04:45+00:00","breadcrumb":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/#primaryimage","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/hello-i-m-nik-LUYD2b7MNrg-unsplash.jpg","contentUrl":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/hello-i-m-nik-LUYD2b7MNrg-unsplash.jpg","width":1024,"height":683},{"@type":"BreadcrumbList","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/solucoes-faceis-para-problemas-dificeis-rest\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/"},{"@type":"ListItem","position":2,"name":"Volume 1","item":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/"},{"@type":"ListItem","position":3,"name":"AP-A Solu\u00e7\u00f5es f\u00e1ceis para problemas dif\u00edceis REST"}]},{"@type":"WebSite","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/","name":"Manual do Arquiteto de Software","description":"","publisher":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization","name":"EximiaCo","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg","contentUrl":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg","width":150,"height":150,"caption":"EximiaCo"},"image":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/facebook.com\/eximiaco","https:\/\/x.com\/eximiaco"]}]}},"_links":{"self":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/volume-1\/2069","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/volume-1"}],"about":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/types\/volume-1"}],"replies":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/comments?post=2069"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/media\/2085"}],"wp:attachment":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/media?parent=2069"}],"wp:term":[{"taxonomy":"url","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/url?post=2069"},{"taxonomy":"sessoes","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/sessoes?post=2069"},{"taxonomy":"apendices","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/apendices?post=2069"},{"taxonomy":"capitulos","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/capitulos?post=2069"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}