Passo a passo para criar e usar uma API REST em Java

Quer aprender a criar e consumir uma API REST em Java puro? Este guia prático te mostra como fazer isso, utilizando com.sun.net.httpserver para criar a API e java.net.HttpURLConnection para consumi-la. Vamos construir um servidor HTTP simples e um cliente para interagir com ele, tudo em Java puro. Prepare-se para colocar a mão na massa e criar sua própria API!

Estrutura do Projeto

Antes de começar a codificar, é importante organizar o projeto. A estrutura de diretórios que usaremos é a seguinte:


src
└── main
    └── java
        ├── api
        │   ├── Task.java          // Modelo de dados
        │   ├── TaskHandler.java   // Manipulador de requisições
        │   └── Server.java        // Servidor principal
        └── client
            └── ApiClient.java     // Cliente para consumir a API

Essa estrutura facilita a organização do código, separando as classes responsáveis pela API (servidor) das classes responsáveis por consumir a API (cliente). Dentro do pacote api, teremos o modelo de dados (Task.java), o manipulador de requisições (TaskHandler.java) e o servidor principal (Server.java). No pacote client, teremos a classe ApiClient.java, que será responsável por interagir com a API.

Código do Servidor

Agora, vamos implementar o código do servidor, começando com a classe Task, que representa o modelo de dados.

Classe Task (Modelo)

A classe Task é um modelo simples que representa uma tarefa com um ID, título e status de conclusão. Veja o código:


package api;

public class Task {
    private int id;
    private String title;
    private boolean completed;

    // Construtor, getters e setters
    public Task(int id, String title, boolean completed) {
        this.id = id;
        this.title = title;
        this.completed = completed;
    }

    public int getId() { return id; }
    public String getTitle() { return title; }
    public boolean isCompleted() { return completed; }
}

Esta classe define os atributos de uma tarefa e fornece métodos para acessar esses atributos. O construtor permite criar instâncias de Task com valores iniciais para ID, título e status de conclusão. Os métodos getId(), getTitle() e isCompleted() são getters que retornam os valores dos respectivos atributos.

Classe TaskHandler (Manipulador de Requisições)

A classe TaskHandler é responsável por manipular as requisições HTTP que chegam ao servidor. Ela implementa a interface HttpHandler e define a lógica para lidar com diferentes métodos HTTP, como GET e POST. Veja o código:


package api;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

public class TaskHandler implements HttpHandler {
    private List<Task> tasks = new ArrayList<>();
    private int nextId = 1;

    @Override
    public void handle(HttpExchange exchange) throws IOException {
        String method = exchange.getRequestMethod();
        String path = exchange.getRequestURI().getPath();

        switch (method) {
            case "GET":
                handleGet(exchange);
                break;
            case "POST":
                handlePost(exchange);
                break;
            default:
                sendResponse(exchange, 405, "{\"error\": \"Método não permitido\"}");
        }
    }

    private void handleGet(HttpExchange exchange) throws IOException {
        String json = "[";
        for (Task task : tasks) {
            json += String.format(
                "{\"id\": %d, \"title\": \"%s\", \"completed\": %b},",
                task.getId(), task.getTitle(), task.isCompleted()
            );
        }
        json = json.isEmpty() ? "[]" : json.substring(0, json.length() - 1) + "]";
        sendResponse(exchange, 200, json);
    }

    private void handlePost(HttpExchange exchange) throws IOException {
        String body = new String(exchange.getRequestBody().readAllBytes());
        // Simples parsing (em produção, use uma biblioteca JSON)
        String title = body.split("\"")[3]; // Extrai o título do JSON
        Task task = new Task(nextId++, title, false);
        tasks.add(task);
        sendResponse(exchange, 201, "{\"id\": " + task.getId() + "}");
    }

    private void sendResponse(HttpExchange exchange, int statusCode, String response) throws IOException {
        exchange.getResponseHeaders().set("Content-Type", "application/json");
        exchange.sendResponseHeaders(statusCode, response.getBytes().length);
        try (OutputStream os = exchange.getResponseBody()) {
            os.write(response.getBytes());
        }
    }
}

A classe TaskHandler mantém uma lista de tarefas (tasks) e um contador para gerar IDs únicos (nextId). O método handle() é o ponto de entrada para todas as requisições. Ele verifica o método HTTP e o caminho da requisição e chama o método apropriado para lidar com a requisição. Os métodos handleGet() e handlePost() implementam a lógica para listar tarefas e criar novas tarefas, respectivamente. O método sendResponse() envia a resposta HTTP de volta para o cliente.

Classe Server (Iniciar Servidor)

A classe Server é responsável por iniciar o servidor HTTP e registrar o TaskHandler para lidar com as requisições na rota /tasks. Veja o código:


package api;

import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.net.InetSocketAddress;

public class Server {
    public static void main(String[] args) throws IOException {
        HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
        server.createContext("/tasks", new TaskHandler());
        server.start();
        System.out.println("Servidor iniciado na porta 8080");
    }
}

O método main() cria uma instância de HttpServer, registra o TaskHandler para a rota /tasks e inicia o servidor na porta 8080. Ele também imprime uma mensagem no console informando que o servidor foi iniciado.

Consumindo a API com ApiClient

Agora que o servidor está pronto, vamos criar um cliente para interagir com a API. A classe ApiClient será responsável por enviar requisições HTTP para o servidor e receber as respostas. Veja o código:


package client;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStream;
import java.io.InputStream;
import java.util.Scanner;

public class ApiClient {

    public static String get(String url) throws IOException {
        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        conn.setRequestMethod("GET");

        try (InputStream is = conn.getInputStream();
             Scanner scanner = new Scanner(is)) {
            return scanner.useDelimiter("\\A").next();
        }
    }

    public static String post(String url, String jsonBody) throws IOException {
        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setDoOutput(true);

        try (OutputStream os = conn.getOutputStream()) {
            os.write(jsonBody.getBytes());
        }

        try (InputStream is = conn.getInputStream();
             Scanner scanner = new Scanner(is)) {
            return scanner.useDelimiter("\\A").next();
        }
    }

    public static void main(String[] args) {
        try {
            // POST: Criar uma tarefa
            String responsePost = post("http://localhost:8080/tasks", 
                "{\"title\": \"Aprender Java\", \"completed\": false}");
            System.out.println("POST Response: " + responsePost);

            // GET: Listar tarefas
            String responseGet = get("http://localhost:8080/tasks");
            System.out.println("GET Response: " + responseGet);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

A classe ApiClient possui métodos para enviar requisições GET e POST para o servidor. O método get() envia uma requisição GET para a URL especificada e retorna a resposta do servidor como uma String. O método post() envia uma requisição POST com um corpo JSON para a URL especificada e retorna a resposta do servidor como uma String. O método main() demonstra como usar os métodos get() e post() para interagir com a API.

Execução

Para executar o servidor e o cliente, siga os seguintes passos:

  1. Inicie o Servidor:
    
       java api.Server
    
  2. Execute o Cliente:
    
       java client.ApiClient
    

Testando com cURL (Opcional)

Se preferir, você pode testar a API usando o cURL, uma ferramenta de linha de comando para fazer requisições HTTP. Aqui estão alguns exemplos:


# Criar tarefa
curl -X POST -H "Content-Type: application/json" -d "{\"title\":\"Estudar API\",\"completed\":false}" http://localhost:8080/tasks

# Listar tarefas
curl http://localhost:8080/tasks

Considerações Finais

Este guia mostrou como criar e consumir uma API REST em Java puro de forma simples e direta. No entanto, é importante ter em mente algumas considerações:

  • Simplicidade vs. Robustez:
    • O servidor usa com.sun.net.httpserver, ideal para protótipos. Em produção, prefira frameworks como Spring Boot ou Javalin.
    • O parsing de JSON é simplificado. Use bibliotecas como Jackson ou Gson para manipulação real de JSON.
  • Cliente HTTP:
    • Para projetos reais, use HttpClient (Java 11+) ou bibliotecas como OkHttp.
  • Melhorias Possíveis:
    • Adicionar tratamento de erros.
    • Implementar métodos PUT e DELETE.
    • Validar entradas.

Com este conhecimento, você pode começar a construir APIs mais complexas e robustas em Java. Lembre-se de explorar as bibliotecas e frameworks disponíveis para facilitar o desenvolvimento e garantir a qualidade do seu código.

Este conteúdo foi auxiliado por Inteligência Artificial, mas escrito e revisado por um humano.Via Dev.to

Leave a Comment

Exit mobile version