Criando uma API RESTful com o Carter e .NET Core \| TreinaWeb               Promoção no ar   Matricule-se agora e garanta **54% de desconto**  

  Termina em   Tempo restante da oferta: 21 Horas 

 24 Min 

 31 Seg 

   Tempo restante da oferta: 21 24 31 

  [Assinar →](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26) 

   [                ](https://www.treinaweb.com.br)  Explorar  

 [ Quanto custa? ](#assinatura) [ FAQ ](https://www.treinaweb.com.br#faq) [Matricule-se](#assinatura) [ Entrar ](https://www.treinaweb.com.br/login) 

     [ Início ](https://www.treinaweb.com.br) [ Artigos ](https://www.treinaweb.com.br/blog) Criando uma API RESTful com o Carter e .NET Core  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) [ ASP .NET ](https://www.treinaweb.com.br/blog/categoria/asp-net) 

# Criando uma API RESTful com o Carter e .NET Core

 O Carter é um framework para .NET Core, que permite criar API RESTful de forma rápida, simples e elegante. O conheça neste artigo.

 [ Wladimilson M. Nascimento ](https://www.treinaweb.com.br/blog/autor/wladimilson-m-nascimento) 7 anos atrás

  ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/12/03143715/CARTER.png)  

No início deste ano comentei o quanto o [ASP.NET Web API é quase uma unanimidade na criação de APIs no .NET](https://www.treinaweb.com.br/blog/criando-uma-api-restful-com-o-nancyfx-e-net-core/), mas que haviam outras opções, tão boas quanto ele.

No artigo em questão abordei a criação de uma API com o framework [NancyFX](http://nancyfx.org/). E ao longo deste ano ganhou destaque outro framework para criação de APIs, que podemos chamar de um derivado do **Nancy**, o **Carter**.

[  ![C# (C Sharp) - APIs REST com ASP.NET Web API](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/csharp.svg)   Curso C# (C Sharp) - APIs REST com ASP.NET Web API Conhecer o curso ](https://www.treinaweb.com.br/curso/c-sharp-apis-rest-com-asp-net-web-api)

## Carter

O **Carter** foi criado por Jonathan Channon, e é mantido por ele e a [Carter Community](https://github.com/CarterCommunity), seguindo a mesma filosofia do *Nancy* (onde o Jonathan Channon também contribui), facilitar a vida do desenvolvedor.

Implementado como uma extensão do ASP.NET Core, o Carter permite que o código seja mais direto, elegante e agradável. Seu principal objetivo é facilitar a definição das rotas e controllers.

Para compreendê-lo, vamos ver um exemplo simples de API.

## Criando a aplicação para utilizar o Carter

O Carter pode ser adicionado em qualquer tipo de aplicação ASP.NET Core, mesmo uma aplicação existente. Caso queria trabalhar apenas com este framework é necessário criar uma aplicação web vazia:

```dos
dotnet new web -n CarterAPI

```

E adicionar o pacote `carter`:

```dos
dotnet add package carter

```

Em seguida ele deve ser configurado na classe `Startup`:

```csharp
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCarter();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseRouting();

        app.UseEndpoints(endpoints => endpoints.MapCarter());
    }
}

```

Também é possível instalar o `CarterTemplate`:

```dos
dotnet new -i CarterTemplate

```

Com isso, é possível criar a aplicação utilizando este template:

```dos
dotnet new Carter -n CarterAPI

```

Nesta opção a aplicação é criada com o Carter configurado e um módulo definido. Como não optamos por esta opção, vamos criar o módulo na nossa aplicação.

## Criando um módulo

Assim como no Nancy, no Carter os endpoints devem ser definidos em módulos. Um módulo nada mais é que uma classe que herde a classe `CarterModule`. Esta classe pode ser definida em qualquer ponto da aplicação. O importante é que seja pública, por exemplo:

```csharp
using Carter;

namespace CarterAPI.Modules
{
    public class HomeModule : CarterModule
    {
        public HomeModule()
        {
            Get("/", (req, res) => res.WriteAsync("Hello from Carter!"));
        }
    }
}

```

Como é possível supor, acima estamos definindo uma solicitação GET, que será invocada quando o usuário acessar a rota `/`. Ao executar a aplicação, teremos o resultado:

![](https://dkrn4sk0rn31v.cloudfront.net/2019/12/03144415/carter_1.png)

Para cada verbo do HTTP há um método disponível:

- `Delete` = `DELETE`;
- `Get` = `GET`;
- `Head` = `HEAD`;
- `Options` = `OPTIONS`;
- `Post` = `POST`;
- `Put` = `PUT`;
- `Patch` = `PATCH`.

## Criando o CRUD

Para exemplificar uma API REST completa, vamos definir os métodos CRUD.

Inicialmente defina uma entidade:

```csharp
public class Pessoa
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public int Idade { get; set; }
}

```

E um repositório:

```csharp
public class PessoaRepository
{
    private static Dictionary pessoas = new Dictionary();

    public List GetAll(){
        return pessoas.Values.ToList();
    }

    public Pessoa Get(int id){
        return pessoas.GetValueOrDefault(id);
    }

    public void Add(Pessoa pessoa){
        pessoas.Add(pessoa.Id, pessoa);
    }

    public void Edit(Pessoa pessoa){
        pessoas.Remove(pessoa.Id);
        pessoas.Add(pessoa.Id, pessoa);
    }

    public void Delete(int id){
        pessoas.Remove(id);
    }
}

```

Por fim, podemos definir os endpoints:

```csharp
public class PessoaModule : CarterModule
{
    public readonly PessoaRepository repository;
    public PessoaModule()
    {
        repository = new PessoaRepository();
        Get("/pessoa/", (req, res) => {
            var pessoas = repository.GetAll();
            return res.AsJson(pessoas);
        });
        Get("/pessoa/{id:int}", (req, res) =>
        {
            var id = req.RouteValues.As("id");
            var pessoa = repository.Get(id);
            return res.Negotiate(pessoa);
        });
        Post("/pessoa/", async (req, res) =>
        {
            var pessoa = await req.Bind();

            repository.Add(pessoa);
            res.StatusCode = 201;
            await res.Negotiate(pessoa);
            return;
        });
        Put("/pessoa/{id:int}", async (req, res) =>
        {
            var pessoa = await req.Bind();

            pessoa.Id = req.RouteValues.As("id");

            repository.Edit(pessoa);

            res.StatusCode = 204;
            return;
        });
        Delete("/pessoa/{id:int}", (req, res) =>
        {
            var id = req.RouteValues.As("id");
            repository.Delete(id);
            res.StatusCode = 204;
            return Task.CompletedTask;
        });
    }
}

```

Nestes endpoints podemos notar algumas particularidades do framework, como o fato dos parâmetros da URL definem um tipo de dado:

```csharp
Get("/pessoa/{id:int}", (req, res) =>

```

Isso permite que o valor seja validado no momento que a solicitação está sendo processada. Este valor é obtido através do método do `RouteValues`:

```csharp
var id = req.RouteValues.As("id");

```

Já os dados passados no corpo da solicitação serão obtidos através do `Bind`:

```csharp
var pessoa = await req.Bind();

```

Podemos testar este endpoint pelo Postman, mas outro recurso do Carter é a geração do JSON definido pelo [OpenAPI](https://www.openapis.org/), que abordei no meu [artigo sobre o Swagger](https://www.treinaweb.com.br/blog/documentando-uma-asp-net-core-web-api-com-o-swagger/).

## OpenAPI

O JSON do OpenAPI criado pelo Carter pode ser acessado pela URL `/openapi`, mas infelizmente ele não configura os endpoints automaticamente. Cada endpoint precisa ser configurado em uma classe que herde `RouteMetaData`.

Para os endpoints deste artigo, defini as classes abaixo:

```csharp
public class GetPessoa : RouteMetaData
{
    public override string Tag { get; } = "Pessoa";
    public override string Description { get; } = "Retorna uma lista de pessoas";

    public override RouteMetaDataResponse[] Responses { get; } =
    {
        new RouteMetaDataResponse
        {
            Code = 200,
            Description = $"Uma lista de Pessoas",
            Response = typeof(IEnumerable)
        }
    };

    public override string OperationId { get; } = "Pessoa_GetPessoa";
}

```

```csharp
public class GetPessoaById: RouteMetaData
{
    public override string Tag { get; } = "Pessoa";
    public override string Description { get; } = "Obtém pessoa pelo id";

    public override RouteMetaDataResponse[] Responses { get; } =
    {
        new RouteMetaDataResponse
        {
            Code = 200, 
            Description = $"Uma Pessooa",
            Response = typeof(Pessoa)
        },
        new RouteMetaDataResponse
        {
            Code = 404,
            Description = $"Pessoa não encontrada"
        }
    };

    public override string OperationId { get; } = "Pessoa_GetPessoaById";
}

```

```csharp
public class PostPessoa: RouteMetaData
{
    public override string Tag { get; } = "Pessoa";
    public override string Description { get; } = "Adiciona uma pessoa";

    public override RouteMetaDataRequest[] Requests { get; } =
    {
        new RouteMetaDataRequest
        {
            Request = typeof(Pessoa),
        }
    };

    public override RouteMetaDataResponse[] Responses { get; } = 
    { 
        new RouteMetaDataResponse 
        { 
            Code = 204, 
            Description = "Pessoa adicionada" 
        }
    };
    public override string OperationId { get; } = "Pessoa_PostPessoa";
}

```

```csharp
public class PutPessoa: RouteMetaData
{
    public override string Tag { get; } = "Pessoa";
    public override string Description { get; } = "Atualiza uma pessoa";

    public override RouteMetaDataRequest[] Requests { get; } =
    {
        new RouteMetaDataRequest
        {
            Request = typeof(Pessoa),
        }
    };

    public override RouteMetaDataResponse[] Responses { get; } = 
    { 
        new RouteMetaDataResponse 
        { 
            Code = 204, 
            Description = "Pessoa atualizada" 
        }
    };
    public override string OperationId { get; } = "Pessoa_PutPessoa";
}

```

```csharp
public class DeletePessoa: RouteMetaData
{
    public override string Tag { get; } = "Pessoa";
    public override string Description { get; } = "Exclui uma pessoa";

    public override RouteMetaDataResponse[] Responses { get; } = 
    { 
        new RouteMetaDataResponse 
        { 
            Code = 204, 
            Description = "Exclui Pessoa" 
        }
    };

    public override string OperationId { get; } = "Pessoa_DeletePessoa";
}

```

Agora é necessário definir esses meta dados em cada endpoint:

```csharp
public class PessoaModule : CarterModule
{
    public readonly PessoaRepository repository;
    public PessoaModule()
    {
        repository = new PessoaRepository();
        Get("/pessoa/", (req, res) => {
            var pessoas = repository.GetAll();
            return res.AsJson(pessoas);
        });
        Get("/pessoa/{id:int}", (req, res) =>
        {
            var id = req.RouteValues.As("id");
            var pessoa = repository.Get(id);
            if(pessoa == null)
            {
                res.StatusCode = 404;
                return Task.CompletedTask;
            }
            return res.Negotiate(pessoa);
        });
        Post("/pessoa/", async (req, res) =>
        {
            var pessoa = await req.Bind();

            repository.Add(pessoa);
            Console.WriteLine(pessoa);
            res.StatusCode = 201;
            await res.Negotiate(pessoa);
            return;
        });
        Put("/pessoa/{id:int}", async (req, res) =>
        {
            var pessoa = await req.Bind();

            pessoa.Id = req.RouteValues.As("id");

            repository.Edit(pessoa);

            res.StatusCode = 204;
            return;
        });
        Delete("/pessoa/{id:int}", (req, res) =>
        {
            var id = req.RouteValues.As("id");
            repository.Delete(id);
            res.StatusCode = 204;
            return Task.CompletedTask;
        });
    }
}

```

Note que eles são especificados no método do endpoint:

```csharp
Get("/pessoa/", (req, res) => {

```

Ao defini-los e acessar `/openapi`, será retornado o JSON:

![](https://dkrn4sk0rn31v.cloudfront.net/2019/12/03144554/carter_2.png)

Para visualizarmos em uma interface gráfica, é possível adicionar o SwaggerUi da biblioteca [Swashbuckle](https://github.com/domaindrivendev/Swashbuckle):

```dos
dotnet add package Swashbuckle.AspNetCore.SwaggerUi --version 5.0.0-rc4

```

Configurá-lo no projeto:

```csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();

    app.UseSwaggerUI(opt =>
    {
        opt.RoutePrefix = "openapi/ui";
        opt.SwaggerEndpoint("/openapi", "Carter OpenAPI Sample");
    });

    app.UseEndpoints(endpoints => endpoints.MapCarter());
}

```

Desta forma, ao acessar a URL `/openapi/ui` teremos acesso a interface gráfica:

![](https://dkrn4sk0rn31v.cloudfront.net/2019/12/03144655/carter_3.png)

E por ela é possível testar todos os endpoints.

[  ![ASP.NET Core - Fundamentos](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/aspnet-core.svg)   Curso ASP.NET Core - Fundamentos Conhecer o curso ](https://www.treinaweb.com.br/curso/aspnet-core-fundamentos)

## Conclusão

Devido a sua simplicidade e grande gama de recursos o Carter é um framework que merece ser acompanhado. Caso tenha se interessado por ele, recomendo que dê uma olhada no seu [repositório](https://github.com/CarterCommunity/Carter).

Infelizmente no momento ele não possui nenhuma documentação detalhada.

Você pode obter os códigos da aplicação demonstrada neste artigo, no meu [Github](https://github.com/wladimilson/carterapi).

- [ #C# ](https://www.treinaweb.com.br/blog/tag/csharp)
- [ #.NET Core ](https://www.treinaweb.com.br/blog/tag/net-core)
- [ #ASP .NET Core ](https://www.treinaweb.com.br/blog/tag/asp-net-core)
- [ #Web API ](https://www.treinaweb.com.br/blog/tag/web-api)
- [ #Swagger ](https://www.treinaweb.com.br/blog/tag/swagger)
- [ #Carter ](https://www.treinaweb.com.br/blog/tag/carter)
- [ #OpenAPI ](https://www.treinaweb.com.br/blog/tag/openapi)

Autor

 ![Wladimilson M. Nascimento](//secure.gravatar.com/avatar/f0dd442f156a3eacd2880e9cd0eafbd1?d=mm)

## Wladimilson M. Nascimento

 Instrutor, nerd, cinéfilo e desenvolvedor nas horas vagas. Graduado em Ciências da Computação pela Universidade Metodista de São Paulo. 

 [Todos os artigos](https://www.treinaweb.com.br/blog/autor/wladimilson-m-nascimento)  

## Continue estudando

 Transforme leitura em prática com os cursos e formações da TreinaWeb.

 [Ver cursos](https://www.treinaweb.com.br/cursos)   

  Continue lendo

## Artigos relacionados

- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/05/criando-api-restful-jax-rs-api-400x280.png)  [ Java ](https://www.treinaweb.com.br/blog/categoria/java) 

     7 anos atrás

    ##  [ Criando uma API RESTful com a JAX-RS API ](https://www.treinaweb.com.br/blog/criando-uma-api-restful-com-a-jax-rs-api) 

     O Java define a especificação JAX-RS API para a criação de aplicações API RESTful, que pode ser facilmente utilizada com a implementação do Jersey.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/11/03160827/NANCY-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     8 anos atrás

    ##  [ Criando uma API RESTful com o NancyFx e .NET Core ](https://www.treinaweb.com.br/blog/criando-uma-api-restful-com-o-nancyfx-e-net-core) 

     O NancyFX é um leve framework para o C#. Veja como utilizá-lo para criar uma API RESTful.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/08/asp-net-conhecendo-as-minimal-api-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     4 anos atrás

    ##  [ ASP.NET - Conhecendo a Minimal API ](https://www.treinaweb.com.br/blog/asp-net-conhecendo-as-minimal-api) 

     Neste artigo vamos conhecer um dos recursos que foram adicionados no .NET 6/ASP.NET 6, que é um novo template de aplicações Web, a Minimal API.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/12/16113045/GRPC-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     7 anos atrás

    ##  [ Serviços gRPC no ASP.NET Core ](https://www.treinaweb.com.br/blog/servicos-grpc-no-asp-net-core) 

     Aprenda o que é gRPC e como criar um serviço com esta tecnologia no ASP.NET Core.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/09/09160454/SGBDs-400x280.png)  [ Bancos de Dados ](https://www.treinaweb.com.br/blog/categoria/bancos-de-dados) 

     5 anos atrás

    ##  [ Tipos de banco de dados NoSQL ](https://www.treinaweb.com.br/blog/tipos-de-banco-de-dados-nosql) 

     Veja neste artigo os principais tipos de banco de dados NoSQL.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/01/criando-uma-api-com-spring-data-jpa-e-spring-web-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     5 anos atrás

    ##  [ Criando uma API com Spring Data JPA e Spring Web ](https://www.treinaweb.com.br/blog/criando-uma-api-com-spring-data-jpa-e-spring-web) 

     Neste artigo vamos aprender como criar uma API com persistência de dados utilizando o Spring Web MVC e o Spring Data JPA.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/07/05112250/SPRING-BOOT-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     7 anos atrás

    ##  [ Criando uma API REST com o Spring Boot ](https://www.treinaweb.com.br/blog/criando-uma-api-rest-com-o-spring-boot) 

     Todos os passos da criação de uma API REST com o framework Spring Boot do Java, no Visual Studio Code.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/04/16095041/OCELOT-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     8 anos atrás

    ##  [ Criando um API Gateway com ASP.NET Core e Ocelot ](https://www.treinaweb.com.br/blog/criando-um-api-gateway-com-asp-net-core-e-ocelot) 

     Conheça o conceito de API Gateway e veja como criá-lo em uma aplicação ASP.NET utilizando a biblioteca Ocelot.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/01/06113752/streaming-api-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     7 anos atrás

    ##  [ ASP.NET Core - Criando uma Streaming API ](https://www.treinaweb.com.br/blog/asp-net-core-criando-uma-streaming-api) 

     Streaming não se resume apenas a conteúdo de media. Aprenda neste artigo como criar uma streaming API de dados no ASP.NET Core.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/03/o-que-e-fastapi-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     4 anos atrás

    ##  [ Criando o primeiro CRUD com FastAPI ](https://www.treinaweb.com.br/blog/criando-o-primeiro-crud-com-fastapi) 

     Neste artigo nós iremos aprender um pouco mais sobre o FastAPI durante o desenvolvimento de uma API com todas as operações de CRUD.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/01/05103838/SIGNALR-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     7 anos atrás

    ##  [ Criando um Chat com ASP.NET Core SignalR ](https://www.treinaweb.com.br/blog/criando-um-chat-com-asp-net-core-signalr) 

     Continuando o estudo do SignalR, aprenda como criar um chat utilizando esta biblioteca de aplicações em tempo real do ASP.NET Core.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/01/10094842/service-stack-1-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     9 anos atrás

    ##  [ Criando um Web Service com o ServiceStack - Parte 1 ](https://www.treinaweb.com.br/blog/criando-um-web-service-com-o-servicestack-parte-1) 

     Nesta primeira parte, veja como criar um web service simples no .NET Core utilizando a biblioteca ServiceStack.

     Ler artigo

## Um ano de acesso total para você viver de programação.

 Todos os cursos e formações da TreinaWeb numa única assinatura, com professores que atuam no mercado, suporte direto e certificados. Do primeiro `console.log` ao mercado de trabalho.

- **1 ano** de acesso a **todos os cursos**
- Cursos novos **toda semana**
- Suporte **direto com professores**
- Plano de carreira **personalizado**
- **Certificados digitais** inclusos
- **Aplicativos** para Android e iOS, com **acesso offline**

    **Garantia incondicional de satisfação** 

 Teste por 7 dias e, se não fizer sentido para você, devolvemos seu dinheiro.

### Acesso completo a todos os cursos e dezenas de Formações.

 12 meses 

  Economize R$ 840,00  54% OFF 

 de 12x R$ 129,00 por apenas

 12x  R$ 59,00

 sem juros no cartão de crédito ou R$ 599,00 à vista

  Oferta termina em  **21h 24min 31s**

- Acesso imediato e ilimitado durante 1 ano.
- Plano de carreira personalizado.
- Suporte direto com professores.
- E muito mais!

 [Matricule-se agora](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26)

     [                ](https://www.treinaweb.com.br)

 Escola online de programação, tecnologia e IA.

- [  ](https://www.facebook.com/TreinaWeb/)
- [  ](https://www.instagram.com/treinaweb/)
- [  ](https://www.youtube.com/user/TreinaWeb)
- [  ](https://twitter.com/treinaweb)
- [  ](https://www.linkedin.com/company/treinaweb)
- [  ](https://github.com/treinaweb)

## Inscreva-se em nossa newsletter

Receba lançamentos, promoções e novidades.

   Seu nome     Seu WhatsApp     Seu melhor e-mail   Inscrever-se 

## Cursos

- [ Base para Devs ](https://www.treinaweb.com.br/categoria/base-para-devs)
- [ Front-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-front-end)
- [ Back-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-back-end)
- [ Mobile ](https://www.treinaweb.com.br/categoria/desenvolvimento-mobile)
- [ Bancos de Dados ](https://www.treinaweb.com.br/categoria/bancos-de-dados)
- [ Cloud ](https://www.treinaweb.com.br/categoria/cloud-computing)
- [ IA ](https://www.treinaweb.com.br/categoria/ia)
- [ E mais ](https://www.treinaweb.com.br/categoria/e-mais)
- [ Ver todos os cursos ](https://www.treinaweb.com.br/cursos)

## Conteúdo

- [ Formações ](https://www.treinaweb.com.br/formacoes)
- [ Projetos práticos ](https://www.treinaweb.com.br/projetos-praticos)
- [ Direto ao ponto ](https://www.treinaweb.com.br/direto-ao-ponto)
- [ Planos ](https://www.treinaweb.com.br#assinatura)
- [ Depoimentos ](https://www.treinaweb.com.br#depoimentos)
- [ Comunidade ](https://www.treinaweb.com.br#comunidade)
- [ Corpo docente ](https://www.treinaweb.com.br#docente)

## A empresa

- [ Sobre a TreinaWeb ](https://www.treinaweb.com.br#sobre)
- [ Perguntas frequentes ](https://www.treinaweb.com.br#faq)
- [ Vantagens de estudar na TreinaWeb ](https://www.treinaweb.com.br/vantagens-de-estudar-na-treinaweb)
- [ Cursos para empresas ](https://www.treinaweb.com.br/empresas)
- [ Sugira um novo curso ](https://www.treinaweb.com.br/sugerir-curso)
- [ Trabalhe conosco ](https://www.treinaweb.com.br/trabalhe-conosco)
- [ Artigos ](https://www.treinaweb.com.br/blog)
- [ Desenvolvedores e agentes ](https://www.treinaweb.com.br/developers)
- [ Contato ](https://www.treinaweb.com.br/contato)
- [ Política de privacidade ](https://www.treinaweb.com.br/politica-de-privacidade)
- [ Termos de uso ](https://www.treinaweb.com.br/termos-de-uso)

## Baixe nosso aplicativo

 [   Disponível na **App Store**  ](https://apps.apple.com/us/app/treinaweb/id1322729447) [   Disponível no **Google Play**  ](https://play.google.com/store/apps/details?id=br.com.treinaweb.mobile) 

  Av. Paulista, 1765, Conj 71 e 72 · Bela Vista · São Paulo · SP · 01311-200   © 2004 – 2026 TreinaWeb Tecnologia LTDA · CNPJ 06.156.637/0001-58
