{"id":1077,"date":"2017-11-03T02:19:42","date_gmt":"2017-11-03T05:19:42","guid":{"rendered":"https:\/\/www.erudio.com.br\/blog\/?p=1077"},"modified":"2022-12-21T14:42:32","modified_gmt":"2022-12-21T17:42:32","slug":"criando-uma-simples-web-api-restful-em-net-core-2-0","status":"publish","type":"post","link":"https:\/\/www.erudio.com.br\/blog\/criando-uma-simples-web-api-restful-em-net-core-2-0\/","title":{"rendered":"Criando uma simples Web API RESTful em .NET Core 2.0"},"content":{"rendered":"<p>Fala pessoal nesse post criaremos uma pequena <strong>API RESTful<\/strong> totalmente do zero. Para isso no <strong>Visual Studio<\/strong> clique em <strong>Arquivo ? Novo ? Projeto<\/strong> ou simplesmente digite <strong>CTRL+Shift+N<\/strong>.<\/p>\n<p><img decoding=\"async\" style=\"max-width: 100%;\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/SimpleRestfulAPIWithAspNetCore\/master\/SimpleRestfulAPIWithAspNetCore-v00%20-%20Scafold\/post\/01.png\" alt=\"Downloading Installer\"><\/p>\n<p>Na tela a seguir selecione Visual <strong>C# ? .NET Core ? Aplicativo Web ASP.NET Core<\/strong>, defina o nome da sua solu\u00e7\u00e3o no meu caso <strong>SimpleRestfulAPIWithAspNetCore <\/strong>e o local em que o nosso c\u00f3digo ser\u00e1 salvo e clique em OK.<\/p>\n<p><img decoding=\"async\" style=\"max-width: 100%;\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/SimpleRestfulAPIWithAspNetCore\/master\/SimpleRestfulAPIWithAspNetCore-v00%20-%20Scafold\/post\/02.png\" alt=\"Downloading Installer\"><\/p>\n<p>Em seguida selecione <strong>API Web<\/strong> e clique em OK. Nesse ponto certifique-se de que <strong>.NET Core<\/strong> e <strong>ASP.NET Core 2.0<\/strong> estejam selecionados.<\/p>\n<p><img decoding=\"async\" style=\"max-width: 100%;\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/SimpleRestfulAPIWithAspNetCore\/master\/SimpleRestfulAPIWithAspNetCore-v00%20-%20Scafold\/post\/03.png\" alt=\"Downloading Installer\"><\/p>\n<p>Pronto nossa <strong>API<\/strong> j\u00e1 foi criada, se voc\u00ea for at\u00e9 o <strong>Gerenciador de Solu\u00e7\u00f5es<\/strong> ver\u00e1 algo muito parecido com a imagem abaixo.<\/p>\n<p><img decoding=\"async\" style=\"max-width: 100%;\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/SimpleRestfulAPIWithAspNetCore\/master\/SimpleRestfulAPIWithAspNetCore-v00%20-%20Scafold\/post\/03.png\" alt=\"Downloading Installer\"><\/p>\n<p>Por padr\u00e3o o <strong>Visual Studio<\/strong> cria as classes <strong>Program.cs<\/strong> e <strong>Startup.cs<\/strong> sendo que a primeira \u00e9 a classe principal da aplica\u00e7\u00e3o e a segunda \u00e9 onde definimos as configura\u00e7\u00f5es de <strong>HTTP<\/strong> e dos servi\u00e7os a serem adicionados ao container. Na pasta <strong>Controllers<\/strong> temos a classe <strong>ValuesController.cs<\/strong> que \u00e9 um template inicial de um servi\u00e7o <strong>REST<\/strong> com as opera\u00e7\u00f5es <strong>GET<\/strong>, <strong>POST<\/strong>, <strong>PUT<\/strong> e <strong>DELETE<\/strong>.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nusing System.Collections.Generic;\nusing Microsoft.AspNetCore.Mvc;\nnamespace SimpleRestfulAPIWithAspNetCore.Controllers\n{\n    [Route(&quot;api\/[controller]&quot;)]\n    public class ValuesController : Controller\n    {\n        \/\/ GET api\/values\n        [HttpGet]\n        public IEnumerable&lt;string&gt; Get()\n        {\n            return new string[] { &quot;value1&quot;, &quot;value2&quot; };\n        }\n\n        \/\/ GET api\/values\/5\n        [HttpGet(&quot;{id}&quot;)]\n        public string Get(int id)\n        {\n            return &quot;value&quot;;\n        }\n\n        \/\/ POST api\/values\n        [HttpPost]\n        public void Post([FromBody]string value)\n        {\n        }\n\n        \/\/ PUT api\/values\/5\n        [HttpPut(&quot;{id}&quot;)]\n        public void Put(int id, [FromBody]string value)\n        {\n        }\n\n        \/\/ DELETE api\/values\/5\n        [HttpDelete(&quot;{id}&quot;)]\n        public void Delete(int id)\n        {\n        }\n    }\n}\n<\/pre>\n<p>Apenas isso \u00e9 o suficiente para criar um primeiro endpoint b\u00e1sico. Se executarmos nossa aplica\u00e7\u00e3o e abrirmos o browser na seguinte URL <strong>http:\/\/localhost:53032\/api\/values<\/strong> nossa aplica\u00e7\u00e3o retornar\u00e1 o valor <strong>[&#8220;value1&#8243;,&#8221;value2&#8221;]<\/strong> que \u00e9 o retorno do nosso endpoint <strong>GET<\/strong>. Entretanto o <strong>REST \u201ccan\u00f4nico\u201d<\/strong> determina que uma verdadeira aplica\u00e7\u00e3o <strong>RESTful <\/strong>deve retornar os status code corretos para cada opera\u00e7\u00e3o. Se quiser uma explica\u00e7\u00e3o mais detalhada sobre <a href=\"https:\/\/www.erudio.com.br\/blog\/http-status-codes-em-servicos-rest\/\">HTTP Status Codes em Servi\u00e7os REST<\/a> confira <a href=\"https:\/\/www.erudio.com.br\/blog\/http-status-codes-em-servicos-rest\/\">esta postagem<\/a> e para entender mais sobre <a href=\"https:\/\/www.erudio.com.br\/blog\/restful-web-services\/\">RESTful Web Services<\/a> confira <a href=\"https:\/\/www.erudio.com.br\/blog\/restful-web-services\/\">esta postagem aqui<\/a>. Os status code mais comumente usados s\u00e3o:<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li><strong>200<\/strong> \u2013 Requisi\u00e7\u00e3o executada com sucesso (OK);<\/li>\n<li><strong>201<\/strong> \u2013 Recurso criado com sucesso;<\/li>\n<li><strong>202<\/strong> \u2013 A requisi\u00e7\u00e3o de atualiza\u00e7\u00e3o foi aceita e ser\u00e1 processada (embora possa ser rejeitada);<\/li>\n<li><strong>204<\/strong> \u2013 Requisi\u00e7\u00e3o processada e n\u00e3o h\u00e1 conte\u00fado de retorno.<\/li>\n<\/ul>\n<p>Al\u00e9m disso, as respostas \u00e0s requisi\u00e7\u00f5es RESTful \u00e0s vezes cont\u00eam informa\u00e7\u00f5es:<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li><strong>200<\/strong> \u2013 <strong>OK<\/strong> \u2013 se requisi\u00e7\u00e3o for <strong>GET<\/strong>, a resposta conter\u00e1 um objeto (ou lista de objetos).<\/li>\n<li><strong>201<\/strong> \u2013 <strong>Created<\/strong> \u2013 a resposta conter\u00e1 o objeto que foi criado e tamb\u00e9m o URI exclusivo necess\u00e1rio para obter esse objeto caso a <strong>API<\/strong> tenha suporte a <strong>HATEOAS<\/strong>. Para entender melhor sobre HATEOAS confira <a href=\"https:\/\/www.erudio.com.br\/blog\/en\/\">esta postagem aqui<\/a> explicando a teoria por tr\u00e1s desse conceito e <a href=\"https:\/\/www.erudio.com.br\/blog\/aplicacoes-restfull-hateoas-com-springboot\/\">esta aqui<\/a> demonstrando na pr\u00e1tica.<\/li>\n<li><strong>202<\/strong> \u2013 <strong>Accepted<\/strong> \u2013 a resposta conter\u00e1 o objeto para o qual uma atualiza\u00e7\u00e3o foi solicitada.<\/li>\n<li><strong>204<\/strong> \u2013 <strong>No content<\/strong> \u2013 isso pode ser retornado como resultado de um pedido de exclus\u00e3o, onde n\u00e3o faria sentido retornar um objeto (j\u00e1 que teoricamente n\u00e3o existe mais). Para alguns te\u00f3ricos mais puristas uma API n\u00e3o deve retornar 204 ( No content), ela deve ajudar o cliente e indicar lugares para ir. Um exemplo de URL a se fornecer \u00e9 a URL da listagem de recursos de onde o cliente acabou de excluir um recurso, talvez ele deseje excluir mais recursos.<\/li>\n<\/ul>\n<p>Levando em conta os <strong>Status Code RESTful<\/strong> destacados acima e de acordo com Jeremy Lindsay o <strong>ValuesControler<\/strong> deveria ser mais \u00fatil e prover uma implementa\u00e7\u00e3o que atenda a essas especifica\u00e7\u00f5es. Sendo assim faremos algumas mudan\u00e7as no nosso servi\u00e7o.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace SimpleRestfulAPIWithAspNetCore.Controllers\n{\n    [Route(&quot;api\/[controller]&quot;)]\n    public class ValuesController : Controller\n    {\n        \/\/ GET api\/values\n        [HttpGet]\n        public IActionResult Get()\n        {\n            return Ok(new string[] { &quot;value1&quot;, &quot;value2&quot; });\n        }\n\n        \/\/ GET api\/values\/5\n        [HttpGet(&quot;{id}&quot;)]\n        public IActionResult Get(int id)\n        {\n            return Ok(&quot;value&quot;);\n        }\n\n        \/\/ POST api\/values\n        [HttpPost]\n        public IActionResult Post([FromBody]string value)\n        {\n            return Created($&quot;api\/Values\/{value}&quot;, value);\n        }\n\n        \/\/ PUT api\/values\/5\n        [HttpPut(&quot;{id}&quot;)]\n        public IActionResult Put(int id, [FromBody]string value)\n        {\n            return Accepted(value);\n        }\n\n        \/\/ DELETE api\/values\/5\n        [HttpDelete(&quot;{id}&quot;)]\n        public IActionResult Delete(int id)\n        {\n            return NoContent();\n        }\n    }\n}\n<\/pre>\n<p>As principais mudan\u00e7as feitas s\u00e3o:<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>O tipo de retorno de cada a\u00e7\u00e3o \u00e9 agora <strong>IActionResult<\/strong>, que permite que os <strong>HTTP Status Code<\/strong> sejam retornados corretamente.<\/li>\n<li>Para as requisi\u00e7\u00f5es <strong>GET<\/strong>, empacotamos retornos (que s\u00e3o strings simples) com um <strong>OK result<\/strong>.<\/li>\n<li>Para a requisi\u00e7\u00e3o <strong>POST<\/strong>, retornamos o objeto criado.<\/li>\n<li>Para a requisi\u00e7\u00e3o <strong>PUT<\/strong>, empacotamos o objeto retornado com o objeto Aceito para atualiza\u00e7\u00e3o.<\/li>\n<li>Finalmente, para a a\u00e7\u00e3o <strong>DELETE<\/strong>, em vez de retornar vazio, devolvemos um tipo de resultado de <strong>NoContent<\/strong>.<\/li>\n<\/ul>\n<h2>Treinamentos relacionados com este post<\/h2>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_rest_asp_net\" target=\"_blank\" rel=\"noopener\"><\/p>\n<p><img decoding=\"async\" style=\"max-width: 100%;\" title=\"REST API's RESTFul do 0 \u00e0 Azure com ASP.NET Core 5 e Docker\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/01-rest-asp.png\"><br \/>\n<\/a><\/p>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_microservices-dotnet\" target=\"_blank\" rel=\"noopener\"><br \/>\n        <img decoding=\"async\" style=\"max-width: 100%;\" title=\"Arquitetura de Microsservi\u00e7os do 0 com ASP.NET, .NET 6 e C#\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/15-microservices-dotnet.png\"><br \/>\n<\/a><\/p>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_docker\" target=\"_blank\" rel=\"noopener\"><br \/>\n        <img decoding=\"async\" style=\"max-width: 100%;\" title=\"Docker do 0 \u00e0 Maestria: Cont\u00eaineres Desmistificados mais 3 B\u00d4NUS\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/09-docker.png\"><br \/>\n<\/a><\/p>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_docker_para_aws\" target=\"_blank\" rel=\"noopener\"><br \/>\n        <img decoding=\"async\" style=\"max-width: 100%;\" title=\"Docker para Amazon AWS Implante Apps Java e .NET com Travis CI\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/10-docker-to-aws.png\"><br \/>\n<\/a><\/p>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_rest_react_asp_net\" target=\"_blank\" rel=\"noopener\"><br \/>\n        <img decoding=\"async\" style=\"max-width: 100%;\" title=\"React JS consumindo REST API RESTful em ASP.NET Core .NET 6\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/17-rest-react-aspnet.png\"><br \/>\n<\/a><\/p>\n<p><\/string><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Fala pessoal nesse post criaremos uma pequena API RESTful totalmente do zero. Para isso no Visual Studio clique em Arquivo ? Novo ? Projeto ou simplesmente digite CTRL+Shift+N. Na tela a seguir selecione Visual C# ? .NET Core ? Aplicativo Web ASP.NET Core, defina o nome da sua solu\u00e7\u00e3o no meu caso SimpleRestfulAPIWithAspNetCore e o [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,11,13,17,96],"tags":[124,134,135,139,221],"_links":{"self":[{"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/posts\/1077"}],"collection":[{"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/comments?post=1077"}],"version-history":[{"count":6,"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/posts\/1077\/revisions"}],"predecessor-version":[{"id":1542,"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/posts\/1077\/revisions\/1542"}],"wp:attachment":[{"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/media?parent=1077"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/categories?post=1077"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/tags?post=1077"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}