Criando um endpoint REST com ASP.NET Core



Neste post daremos continuidade a uma série de postagens sobre Web-Services divididos entre conceitos teóricos e praticos. Nos 3 primeiros posts focou-se em teoria com um sobre Web Services, outro sobre RESTful Web Services e mais um sobre os HTTP Status Codes mais comuns. Este post por sua vez complementa a parte teórica e o que foi desenvolvido na série de posts em que implementamos API’s REST com SpringBoot. Faremos aqui uma abordagem das mesmas situações só que dessa vez com a tecnologia ASP.NET Core. Além disso o código desse projeto se baseia no post anterior Criando um endpoint REST com ASP.NET Core. Então antes de começar confira o post Criando uma simples Web API RESTful em .NET Core 2.0.



Agora faremos algumas alterações no projeto original. Para começar crie os seguintes source folders Models, Services e dentro de Services Implementations. A estrutura da nossa arquitetura deve ficar similar a imagem abaixo.



Arquitetura da Aplicação



Feito isto crie uma classe chamada Person, no source folder Models, com as informações que serão representadas pelo nosso endpoint REST.

namespace SimpleRestfulAPIWithAspNetCore.Models
{
    public class Person
    {
        public long Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Address { get; set; }
    }
}


Feito isto crie uma interface com o nome IPersonService no source folder Services.


using SimpleRestfulAPIWithAspNetCore.Models;
using System.Collections.Generic;

namespace SimpleRestfulAPIWithAspNetCore.Services
{
    public interface IPersonService
    {
        Person Create(Person person);
        Person FindById(string personId);
        List<Person> FindAll();
        Person Update(Person person);
        void Delete(string personId);
    }
}



Agora vamos criar a implementação para a interface PersonService. No source folder Services –> Implementations crie a classe PersonServiceImpl que implementa a interface que acabamos de criar.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SimpleRestfulAPIWithAspNetCore.Models;
using System.Threading;

namespace SimpleRestfulAPIWithAspNetCore.Services.Implementations
{
    public class PersonServiceImpl : IPersonService
    {
        // Contador responsável por gerar um fake ID já que não estamos
        // acessando nenhum banco de dados
        private volatile int count;

        // Metodo responsável por criar uma nova pessoa
        // Se tivéssemos um banco de dados esse seria o
        // momento de persistir os dados
        public Person Create(Person person)
        {
            return person;
        }

        // Método responsável por retornar uma pessoa
        // como não acessamos nenhuma base de dados
        // estamos retornando um mock
        public Person FindById(string personId)
        {
            return new Person
            {
                Id = IncrementAndGet(),
                FirstName = "Leandro",
                LastName = "Costa",
                Address = "Uberlândia - Minas Gerais - Brasil"
            };
        }

        // Método responsável por retornar todas as pessoas
        // mais uma vez essas informações são mocks
        public List<Person> FindAll()
        {
            List<Person> persons = new List<Person>();
            for (int i = 0; i < 8; i++)
            {
                Person person = MockPerson(i);
                persons.Add(person);
            }
            return persons;
        }

        // Método responsável por atualizar uma pessoa
        // por ser mock retornamos a mesma informação passada
        public Person Update(Person person)
        {
            return person;
        }

        // Método responsável por deletar
        // uma pessoa a partir de um ID
        public void Delete(string personId)
        {
            //A nossa lógica de exclusão viria aqui
        }

        // Método responsável por mockar uma pessoa
        private Person MockPerson(int i)
        {
            return new Person
            {
                Id = IncrementAndGet(),
                FirstName = "Person Name " + i,
                LastName = "Last Name " + i,
                Address = "Some Address in Brasil " + i
            };
        }
        
        public Int32 IncrementAndGet()
        {
            return Interlocked.Increment(ref count);
        }
    }
}



Por fim renomeie a classe ValuesController para PersonController, após as alterações esse será o controller responsável por expor o endpoint de pessoas, no source folder Controllers.

using Microsoft.AspNetCore.Mvc;
using SimpleRestfulAPIWithAspNetCore.Models;
using SimpleRestfulAPIWithAspNetCore.Services;

namespace SimpleRestfulAPIWithAspNetCore.Controllers
{
    /* Mapeia as requisições de http://localhost:{porta}/api/person/
    Por padrão o ASP.NET Core mapeia todas as classes que extendem Controller
    pegando a primeira parte do nome da classe em lower case [Person]Controller
    e expõe como endpoint REST
    */
    [Route("api/[controller]")]
    public class PersonController : Controller
    {
        //Declaração do serviço usado
        private IPersonService _personService;

        /* Injeção de uma instancia de IPersonService ao criar
        uma instancia de PersonController */
        public PersonController(IPersonService personService)
        {
            _personService = personService;
        }

        //Mapeia as requisições GET para http://localhost:{porta}/api/person/
        //Get sem parâmetros para o FindAll --> Busca Todos
        [HttpGet]
        public IActionResult Get()
        {
            return Ok(_personService.FindAll());
        }

        //Mapeia as requisições GET para http://localhost:{porta}/api/person/{id}
        //recebendo um ID como no Path da requisição
        //Get com parâmetros para o FindById --> Busca Por ID
        [HttpGet("{id}")]
        public IActionResult Get(string id)
        {
            var person = _personService.FindById(id);
            if (person == null) return NotFound();
            return Ok(person);
        }

        //Mapeia as requisições POST para http://localhost:{porta}/api/person/
        //O [FromBody] consome o Objeto JSON enviado no corpo da requisição
        [HttpPost]
        public IActionResult Post([FromBody]Person person)
        {
            if (person == null) return BadRequest();
            return new ObjectResult(_personService.Create(person));
        }

        //Mapeia as requisições PUT para http://localhost:{porta}/api/person/
        //O [FromBody] consome o Objeto JSON enviado no corpo da requisição
        [HttpPut]
        public IActionResult Put([FromBody]Person person)
        {
            if (person == null) return BadRequest();
            return new ObjectResult(_personService.Update(person));
        }

        //Mapeia as requisições DELETE para http://localhost:{porta}/api/person/{id}
        //recebendo um ID como no Path da requisição
        [HttpDelete("{id}")]
        public IActionResult Delete(string id)
        {
            _personService.Delete(id);
            return NoContent();
        }
    }
}



Agora que terminamos nossa codificação inicie a aplicação. Para testar nosso endpoint e cada uma de suas operações usaremos o plugin do Chrome Postman.


Primeiro faremos uma requisição do tipo GET chamando a operação findAll para o recurso http://localhost:{porta}/api/person/. Como se pode ver na imagem abaixo obtemos como resposta um JSON com um array de pessoas.



Requisição REST do tipo GET



Agora faremos uma requisição do tipo GET chamando a operação http://localhost:{porta}/api/person/1 passando como variável path o ID da pessoa que desejamos recuperar. Da mesma forma que na requisição anterior recebemos como resposta um JSON com 1 objeto pessoa.



Requisição REST do tipo GET passando variavel via PATH

Agora faremos uma requisição do tipo POST (esse é o verbo REST usado para persistir informações) chamando a operação http://localhost:{porta}/api/person/ passando como parâmetro um JSON com um objeto pessoa no corpo da requisição. Para isso no Postman precisamos setar o tipo de requisição como POST, na aba Body definimos o JSON que representa o objeto pessoa a ser gravado, selecionamos a opção raw, definimos a opção JSON(application/json) e por fim executamos a request através do botão send.



Requisição REST do tipo POST gravando um recurso


Agora faremos uma requisição do tipo PUT (esse é o verbo REST usado para atualizar informações) chamando a operação http://localhost:{porta}/api/person/ passando como parâmetro um JSON com um objeto pessoa no corpo da requisição. Lembrando que essa representação de pessoa deve ter um ID que será usado pra localizar e atualizar um recurso na base. Para isso no Postman precisamos setar informações similares ao post a unica diferença é que o tipo de requisição deve ser o PUT.



Requisição REST do tipo PUT atualizando um recurso



Por fim faremos uma requisição do tipo DELETE (verbo REST usado excluir informações) chamando a operação http://localhost:{porta}/api/person/1 passando como variável path o ID da pessoa que desejamos remover da base. Esse tipo de requisição retorna como resposta um body vazio e um StatusCode 200 caso a operação seja executada com sucesso os StatusCode 204 (no content), 401 (Unauthorized), 403 (forbiden), 404 (not found) ou 500 (internal server error) podem ser retornados.



Requisição REST do tipo DELETE removendo um recurso



Dessa forma abordamos os 4 verbos principais do HTTP usados em aplicações REST. Continue ligado no blog, por que no próximo post iremos documentar a nossa API com o framewrok Swagger. E claro a abordagem nesses posts também será totalmente mão na massa. É isso aí bons estudos.

Tags: , , , ,

Criando uma simples Web API RESTful em .NET Core 2.0



Fala rapazeada 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.



Downloading Installer



Na tela a seguir selecione Visual C# → .NET Core → Aplicativo Web ASP.NET Core, defina o nome da sua solução no meu caso SimpleRestfulAPIWithAspNetCore e o local em que o nosso código será salvo e clique em OK.



Downloading Installer



Em seguida selecione API Web e clique em OK. Nesse ponto certifique-se de que .NET Core e ASP.NET Core 2.0 estejam selecionados.



Downloading Installer



Pronto nossa API já foi criada, se você for até o Gerenciador de Soluções verá algo muito parecido com a imagem abaixo.

Downloading Installer

Por padrão o Visual Studio cria as classes Program.cs e Startup.cs sendo que a primeira é a classe principal da aplicação e a segunda é onde definimos as configurações de HTTP e dos serviços a serem adicionados ao container. Na pasta Controllers temos a classe ValuesController.cs que é um template inicial de um serviço REST com as operações GET, POST, PUT e DELETE.


using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
namespace SimpleRestfulAPIWithAspNetCore.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        [HttpPost]
        public void Post([FromBody]string value)
        {
        }

        // PUT api/values/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}



Apenas isso é o suficiente para criar um primeiro endpoint básico. Se executarmos nossa aplicação e abrirmos o browser na seguinte URL http://localhost:53032/api/values nossa aplicação retornará o valor [“value1″,”value2”] que é o retorno do nosso endpoint GET. Entretanto o REST “canônico” determina que uma verdadeira aplicação RESTful deve retornar os status code corretos para cada operação. Se quiser uma explicação mais detalhada sobre HTTP Status Codes em Serviços REST confira esta postagem e para entender mais sobre RESTful Web Services confira esta postagem aqui. Os status code mais comumente usados são:


  • 200 – Requisição executada com sucesso (OK);
  • 201 – Recurso criado com sucesso;
  • 202 – A requisição de atualização foi aceita e será processada (embora possa ser rejeitada);
  • 204 – Requisição processada e não há conteúdo de retorno.



Além disso, as respostas às requisições RESTful às vezes contêm informações:


  • 200OK – se requisição for GET, a resposta conterá um objeto (ou lista de objetos).
  • 201Created – a resposta conterá o objeto que foi criado e também o URI exclusivo necessário para obter esse objeto caso a API tenha suporte a HATEOAS. Para entender melhor sobre HATEOAS confira esta postagem aqui explicando a teoria por trás desse conceito e esta aqui demonstrando na prática.
  • 202Accepted – a resposta conterá o objeto para o qual uma atualização foi solicitada.
  • 204No content – isso pode ser retornado como resultado de um pedido de exclusão, onde não faria sentido retornar um objeto (já que teoricamente não existe mais). Para alguns teóricos mais puristas uma API não deve retornar 204 ( No content), ela deve ajudar o cliente e indicar lugares para ir. Um exemplo de URL a se fornecer é a URL da listagem de recursos de onde o cliente acabou de excluir um recurso, talvez ele deseje excluir mais recursos.



Levando em conta os Status Code RESTful destacados acima e de acordo com Jeremy Lindsay o ValuesControler deveria ser mais útil e prover uma implementação que atenda a essas especificações. Sendo assim faremos algumas mudanças no nosso serviço.


using Microsoft.AspNetCore.Mvc;

namespace SimpleRestfulAPIWithAspNetCore.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public IActionResult Get()
        {
            return Ok(new string[] { "value1", "value2" });
        }

        // GET api/values/5
        [HttpGet("{id}")]
        public IActionResult Get(int id)
        {
            return Ok("value");
        }

        // POST api/values
        [HttpPost]
        public IActionResult Post([FromBody]string value)
        {
            return Created($"api/Values/{value}", value);
        }

        // PUT api/values/5
        [HttpPut("{id}")]
        public IActionResult Put(int id, [FromBody]string value)
        {
            return Accepted(value);
        }

        // DELETE api/values/5
        [HttpDelete("{id}")]
        public IActionResult Delete(int id)
        {
            return NoContent();
        }
    }
}



As principais mudanças feitas são:


  • O tipo de retorno de cada ação é agora IActionResult, que permite que os HTTP Status Code sejam retornados corretamente.
  • Para as requisições GET, empacotamos retornos (que são strings simples) com um OK result.
  • Para a requisição POST, retornamos o objeto criado.
  • Para a requisição PUT, empacotamos o objeto retornado com o objeto Aceito para atualização.
  • Finalmente, para a ação DELETE, em vez de retornar vazio, devolvemos um tipo de resultado de NoContent.

É isso aí bons estudos e se gostou da postagem vá até o topo dessa página e torne-se um membro VIP para receber conteúdos exclusivos.

Tags: , , , ,

Habilitando acesso externo ao IIS Express



Fala rapazeada atualmente eu estou desenvolvendo aplicações REST em ASP.NET e tive que testar uma API desenvolvida em outra máquina. Por padrão, o IIS Express não permite conexões remotas e retorna o seginte erro “Bad Request – Invalid Host Name”. Scott Hanselman fez um post muito bem detalhado a esse respeito. No meu caso eu fiz algumas adaptações e nesse post, eu explico de uma forma mais resumida como habilitar o acesso externo ao IIS express.



1° Passo : Configurando o IIS Express

Normalmente quando você executa uma aplicação no IIS Express, ela pode ser acessada pela URL http://localhost:[numero_da_porta]. Para permitir o acesso externo à aplicações desenvolvidas no Visual Studio 2017, abra o arquivo localizado em <solution>/.vs/config/applicationhost.config, localize a tag <sites> → <site> → <bindings> → <binding ; e duplique a linha de “bindingInformation” contendo localhost adicionando um novo binding para o seu IP. Após as alterações seu arquivo deve ser similar ao trecho de código abaixo.

    <sites>
      
	...

      <site name="RestfulAPIWithAspNet" id="2">
        <application path="/" applicationPool="Clr4IntegratedAppPool">
          <virtualDirectory path="/" physicalPath="C:\Dev\Playground\Code\ASP_NET_Playground\RestfulAPIWithAspNet-v10\RestfulAPIWithAspNet" />
        </application>
        <bindings>
          <binding protocol="http" bindingInformation="*:61533:localhost" /> <!-- Duplique essa linha e adicione um novo binding para o seu IP --> 
          <binding protocol="http" bindingInformation="*:61533:192.168.2.2" /> 
        </bindings>
      </site>
      
	...

    </sites>

Devemos nos lembrar que não é uma boa prática versionar este arquivo.
2° Passo : Permitir Incoming Connections
Se você estiver executando em uma versão igual ou superior ao Windows 7, a maioria dos acessos externos são bloqueados por padrão, então você precisa dar permissão especificamente para as conexões recebidas por sua aplicação. Para fazer isso siga os passos abaixo:



Abra o PowerShell ou o prompt de comandos como “Administrador”;
Execute o comando abaixo:


netsh http add urlacl url=http://*:61533/ user=everyone

Obs: Você deve trocar o número da porta para o que a sua aplicação estiver usando. Além disso se você estiver instalado o Windows em português precisará mudar o user de everyone para todos.


netsh http add urlacl url=http://*:61533/ user=todos



Nesse passo possivelmente você já conseguiu desbloquear o acesso externo.



3° Passo : Configurar o Firewall
Se você chegou até aqui as coisas não estão muito boas, hehehe.


  • Acesse o “Painel de Controle” e vá até “Firewall do Windows”
  • Clique em “Configurações Avançadas”
  • Selecione “Regras de Entrada”
  • Downloading Installer

  • Clique em “Nova Regra…”
  • Selecione “Porta” e clique em “Avançar”
  • Downloading Installer

  • Defina a porta usada pelo IIS Express para sua aplicação e, clique em “Avançar”
  • Downloading Installer

  • Selecione “Permitir a conexão”, clique em “Avançar”
  • Downloading Installer

  • Verifique onde você gostaria de permitir a conexão ao IIS Express (Domínio, Particular, Público), clique em “Avançar”
  • Downloading Installer

  • Defina o nome de sua regra e clique em “Concluir”
  • Downloading Installer

Pronto nossa nova regra foi criada.

Downloading Installer



Se preferir adicionar a regra do firewall via linha de comando basta você adaptar o comando abaixo às suas necessidades.

netsh advfirewall firewall add rule name="IISExpressWeb" dir=in protocol=tcp localport=61533 profile=private remoteip=localsubnet action=allow



Esse comando adiciona uma nova regra ao Firewall do Windows, permitindo conexões externas a porta 61533 para computadores da sua subrede.
Nesse ponto, basta você pressionar Ctrl-F5 no Visual Studio, e acessar sua API ou site em outra máquina! Para situações avançadas acesse o blog do Scott Hanselman.

É isso aí bons estudos e se gostou da postagem vá até o topo dessa página e torne-se um membro VIP para receber conteúdos exclusivos.

Tags: , , ,

Testando serviços REST com Spring Boot e RestTemplate

Uma das principais características do Spring Boot é a sua simplicidade em permitir criar rapidamente uma aplicação sem abrir mão do design do seu código. E se você realmente quer fazer um trabalho de qualidade não pode abrir mão dos testes. Um bom modo de se fazer isso é com testes efetivos (não mocks) rodando no seu ambiente desenvolvimento. No trecho de códigos criamos o nosso primeiro teste.

package br.com.erudio;

import java.io.IOException;
import java.util.List;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import br.com.erudio.models.Person;
import br.com.erudio.repository.PersonRepository;

//Inicializamos o SpringRunner
@RunWith(SpringRunner.class)
//Setamos como uma classe de testes com o Server inicializando em uma porta fixa
//Essa porta pode ser a 8080 ou a que desejarmos setada no nosso aplication.properties
//Acesse src/test/resources/application.properties caso deseje alterar
//No nosso caso é a 8888 como você pode ver no aplication.properties "server.port = 8888"
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class PersonEndpointTests {
    
    //URL base para onde as requests serão feitas
    final String BASE_PATH = "http://localhost:8888/person";

    //Injetamos o repositório para acesso ao Banco de dados
    @Autowired
    private PersonRepository repository;
	
    //Definimos o restTemplate
    private RestTemplate restTemplate;
    
    //Definimos o JacksonMapper responsável por converter
    //JSON para Objeto e vice versa
    private ObjectMapper MAPPER = new ObjectMapper();
    
    //Definimos o que será feito antes da execução do teste
    @Before
    public void setUp() throws Exception {

        //Deletamos todos os registros do banco
        repository.deleteAll();

        //Inserimos alguma pessoas no banco
        repository.save(new Person("Diego", "Samuel", "Asa Sul"));
        repository.save(new Person("Eudes", "Silva", "Rosário"));
        repository.save(new Person("Anderson", "Silva", "Santa Teresa"));
	repository.save(new Person("Alice", "Ferreira", "Bombeiros"));
	repository.save(new Person("Alan", "Franco", "Granja Marileusa"));        
       
        //Inicializamos o objeto restTemplate
        restTemplate = new RestTemplate();
    }
    
    @Test
    public void testCreatePerson() throws JsonProcessingException{

        //Criamos uma nova pessoa
        Person person = new Person("Leandro", "Costa", "Presidente Roosevelt");

        //Fazemos um HTTP request do tipo POST passando a pessoa como parâmetro
        Person response = restTemplate.postForObject(BASE_PATH, person, Person.class);

        //Verificamos se o resultado da requisição é igual ao esperado
        //Se sim significa que tudo correu bem
        Assert.assertEquals("Leandro Costa", response.getFirstName() + " " + response.getLastName());
    }
    
  

}

Agora faremos um HTTP request do tipo GET para listar todas as pessoas ou uma em específico

    @Test
    public void testFindOne() throws IOException{

        //Fazemos uma requisição HTTP GET buscando por todas as pessoas
    	String response = restTemplate
			.getForObject(BASE_PATH + "/findAll", String.class);

        //Convertemos a resposta JSON para Objeto usando op Jackson
        List<Person> persons = MAPPER.readValue(response, 
			MAPPER.getTypeFactory().constructCollectionType(List.class, Person.class));
        //Pegamos o ID da pessoa na posição 1 da lista e fazemos nova requisição
        //Recuperando as informações da mesma
        Person person = restTemplate.getForObject(BASE_PATH + "/" +
			persons.get(1).getIdPerson(), Person.class);
        
        //Verificamos se o resultado da requisição é igual ao esperado
        //Se sim significa que tudo correu bem
        Assert.assertNotNull(person);
    	Assert.assertEquals("Eudes", person.getFirstName());
    	Assert.assertEquals("Silva", person.getLastName());
    }

Agora faremos um HTTP request do tipo PUT para atualizar uma pessoa em específico

    
    @Test
    public void testUpdatePerson() throws IOException{
    	String response = restTemplate.getForObject(BASE_PATH + "/findAll", String.class);
        List<Person> persons = MAPPER.readValue(response,
			MAPPER.getTypeFactory().constructCollectionType(List.class, Person.class));
        
        //Pegamos o ID da pessoa na posição 2 da lista e fazemos nova requisição
        //Recuperando as informações da mesma
        Person person = restTemplate.getForObject(BASE_PATH + "/" +
			persons.get(2).getIdPerson(), Person.class);

        //Alteramos as informações da pessoa recuperada
        person.setFirstName("Tiago");
        person.setLastName("Ferreira");

        //Fazemos um HTTP request do tipo PUT passando a pessoa 
        //e suas novas informações como parâmetro
        restTemplate.put(BASE_PATH, person);
        
        //como a operação PUT do RestTemplate é do tipo void
        //Precisamos fazer uma nova requisição para recuperar 
        //as informações da pessoa atualizada
        Person person2 = restTemplate.getForObject(BASE_PATH + "/" +
			persons.get(2).getIdPerson(), Person.class);
       
        //Verificamos se o resultado da requisição é igual ao esperado
        //Se sim significa que tudo correu bem
        Assert.assertNotNull(person2);
    	Assert.assertEquals("Tiago", person2.getFirstName());
    	Assert.assertEquals("Ferreira", person2.getLastName());
        
    }

Sendo assim nos testamos as operações do nosso endpoint. Se quiser ver mais detalhes você pode baixar o código deste post aqui, descompactar o arquivo zip e importar na sua IDE preferida ou clonar usando Git:


git clone https://github.com/leandrocgsi/spring-boot-rest-with-mongodb-example.git


Você pode acessar outros posts sobre SpringBoot e REST aqui mesmo no blog. É isso aí bons estudos e se gostou da postagem, vá até o topo desta página e torne-se um membro VIP para receber conteúdos exclusivos.

Tags: , ,

Guia Rápido de Docker

Fala rapazeada recentemente eu tirei um tempo pra estudar Docker e usar deploiando aplicações com Spring Boot. Este é minha lista de comandos básicos. Se você tiver alguma dica adicional que não está listada aqui sinta-se livre para mencionar nos comentários e eu irei atualizar o post. Lembrando que a maioria dos comandos podem ser usados em qualquer tipo de aplicação e não apenas com Spring Boot.

Exibir informações do Docker

docker info

Listar Todas as Docker Images

docker images -a

Listar Todos os Docker Containers que estão em execução

docker ps

Listar Todos os Docker Containers

docker ps -a

Iniciar um Docker Container

docker start <container name>

Parar um Docker Container

docker stop <container name>

Reiniciar um Docker Container

docker restart <container name>

Visualizar os logs de um Docker Container em execução

docker logs <container name>

Deletar um Docker Container

Use a opção -f caso precise forçar a remoção.

docker rm <container name>

Deletar Todos os Docker Containers

Use a opção -f caso precise forçar a remoção.

docker rm $(docker ps -a -q)

Remover uma Docker Image

docker rmi <image name>

Remover Todas as Docker Images

docker rmi $(docker images -q)

Acessando o Shell de um Docker Container em execução

sudo docker exec -it <container name> bash

Saindo do Shell de um Docker Container em execução

CTRL+P+Q

Baixando uma imagem do DockerHub

docker pull <image name>

Criando uma Tag de Uma imagem a ser commitada no DockerHub

docker tag <docker hub user>/<image name> <docker hub user>/<image name> 

Autenticar no DockerHub

docker login

Enviar uma imagem para o DockerHub

docker push <docker hub user>/<image name>

Cosntruindo uma imagem a partir de um Dockerfile no diretório atual

docker build -t="<image name>" .

Exibir o histórico de um container em execução

docker history <container name>

Criando um Alias para um comando Docker

alias dps="docker ps"

Limpando o console

reset

Dicas espertas de Dockerfile para developers Spring Boot

Add Oracle Java to an Image

Para Ubuntu versão 16.10 LTS

FROM dockerfile/ubuntu

# Instala o Java 8.
RUN \
  echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections && \
  add-apt-repository -y ppa:webupd8team/java && \
  apt-get update && \
  apt-get install -y oracle-java8-installer && \
  rm -rf /var/lib/apt/lists/* && \
  rm -rf /var/cache/oracle-jdk8-installer


# Define o diretório de trabalho.
WORKDIR /data

# Define a variável de ambiente JAVA_HOME
ENV JAVA_HOME /usr/lib/jvm/java-8-oracle

# Define o comando padrão.
CMD ["bash"]

Adicionando e executando um .jar de uma aplicação Spring Boot a uma Docker Image

VOLUME /tmp
ADD /maven/myapp-0.0.1-SNAPSHOT.jar myapp.jar
RUN sh -c 'touch /myapp.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/myapp.jar"]

É isso aí bons estudos e se gostou da postagem vá até o topo dessa página e torne-se um membro VIP para receber conteúdos exclusivos.

Tags: , ,

Definindo o MongoDB como um serviço.

Em um post anterior você aprendeu como instalar o MongoDB e executá-lo. Entretanto abrir a janela de comando toda vez que quiser usar o MongoDb pode não ser algo muito interessante. Para isso podemos definir o MongoDB como um serviço que se inicializará junto com o sistema operacional. Para isso adapte para o seu cenário e execute o seguinte comando:

mongod --dbpath "{{seu_diretorio_do_mongo}}" --logpath "{{seu_diretorio_do_mongo}}\logs.txt" --install --serviceName "MongoDB"

No meu caso o comando ficou da forma abaixo.

Downloading Installer

Agora tecle WINDOWS + R e na janela que se abre digite services.msc isso irá abrir a tela de serviços do Windows. Procure por nosso novo serviço “MongoDB”.

Downloading Installer

Caso não esteja em inicialização automática defina como tal. E caso esteja parado clique com o direto e clique no botão iniciar.

Downloading Installer

Pronto de agora em diante toda vez que você iniciar o Windows o MongoDB também será inicializado. É isso aí bons estudos e se gostou da postagem vá até o topo dessa página e torne-se um membro VIP para receber conteúdos exclusivos.

Tags: ,