DEV Community

Taui Silva
Taui Silva

Posted on

Personalizando o Swagger UI no Spring Boot: Como Aplicar um Tema Dark

O que é o Swagger?

O Swagger é uma poderosa ferramenta para documentar, testar e interagir com APIs REST, proporcionando uma experiência mais intuitiva para desenvolvedores e consumidores da API. Ele permite visualizar e interagir com endpoints no navegador, facilitando a compreensão e validação do serviço.

No Spring Boot, é integrado via Springdoc OpenAPI, oferecendo uma interface intuitiva para explorar endpoints, visualizar modelos e testar requisições HTTP.

Por padrão, o Swagger usa um design com cores claras. Veja um exemplo:

Swagger-padrão

No entanto, em alguns casos, pode ser necessário personalizar sua aparência para adequá-lo à identidade visual do projeto. Neste artigo, mostrarei como modificar o CSS do Swagger para aplicar um tema escuro (dark mode).


Configurando o projeto

Neste exemplo, utilizaremos as seguintes versões:

  • Spring Boot 3.4.3
  • Springdoc OpenAPI 2.8.5

Se o seu projeto ainda não está configurado, você pode criá-lo rapidamente usando o Spring Initializr.

Adicionando a dependência do Springdoc

No arquivo pom.xml, adicione a seguinte dependência:

<!-- Dependência do Swagger para Spring Boot -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.8.5</version> <!-- Sempre verifique a versão mais recente -->
</dependency>
Enter fullscreen mode Exit fullscreen mode

Configurações básicas do Swagger

Agora, configure o Swagger no arquivo application.properties ou application.yml:

Usando application.properties

# Define o endpoint onde a documentação OpenAPI (Swagger) estará disponível
springdoc.api-docs.path=/api-docs  

# Define a versão do OpenAPI usada na documentação  
springdoc.api-docs.version=openapi_3_1  

# Habilita a interface do Swagger UI  
springdoc.swagger-ui.enabled=true  

# Define o caminho da interface gráfica do Swagger UI  
springdoc.swagger-ui.path=swagger-ui.html  

# Ordena as operações na interface do Swagger UI pelo método HTTP (GET, POST, etc.)  
springdoc.swagger-ui.operationsSorter=method  

# Ordena as tags alfabeticamente na interface do Swagger UI  
springdoc.swagger-ui.tagsSorter=alpha  

# Garante que os cabeçalhos HTTP sejam corretamente repassados quando o app está atrás de um proxy reverso (ex: Nginx, Kubernetes)  
server.forward-headers-strategy=framework  
Enter fullscreen mode Exit fullscreen mode

Usando application.yml

springdoc:
  api-docs:
    path: /api-docs
    version: openapi_3_1
  swagger-ui:
    enabled: true
    path: swagger-ui.html
    operations-sorter: method
    tags-sorter: alpha

server:
  forward-headers-strategy: framework
Enter fullscreen mode Exit fullscreen mode

Configurando a classe principal

Agora, vamos configurar a classe principal da aplicação. O Spring Boot utiliza a anotação @SpringBootApplication para definir o ponto de entrada do projeto. Além disso, podemos utilizar @OpenAPIDefinition para definir informações básicas da documentação Swagger, como título, versão e descrição.

Caso o projeto utilize autenticação com JWT, também podemos configurar um esquema de segurança usando @SecurityScheme. Se o seu projeto não exige autenticação, essa configuração pode ser removida sem impactar o funcionamento do Swagger.

Veja abaixo a estrutura da classe principal:

@SpringBootApplication
@OpenAPIDefinition(info = @Info(
    title = "Título da Aplicação", 
    version = "0.1", 
    description = "Descrição da aplicação"
))
@SecurityScheme(
    name = "bearerAuth",
    description = "JWT auth",
    scheme = "bearer",
    type = SecuritySchemeType.HTTP,
    bearerFormat = "JWT",
    in = SecuritySchemeIn.HEADER
)
public class SwaggerDarkApplication {

    public static void main(String[] args) {
        SpringApplication.run(SwaggerDarkApplication.class, args);
    }
}
Enter fullscreen mode Exit fullscreen mode

Explicação das anotações:

  • @SpringBootApplication → Define a classe principal do projeto Spring Boot.
  • @OpenAPIDefinition → Configura informações básicas da API, como título, versão e descrição.
  • @SecurityScheme (opcional) → Define a autenticação via JWT para proteger a API. Caso seu projeto não use autenticação, essa anotação pode ser removida.

Com tudo configurado, agora podemos iniciar a aplicação e acessar a documentação interativa no Swagger UI através do seguinte caminho:

🔗 http://localhost:8080/swagger-ui/index.html

⚠️ Nota: O exemplo acima usa a porta padrão 8080 do Spring Boot. Se sua aplicação estiver rodando em outra porta, basta ajustá-la na URL conforme necessário.

Inicialização do swagger

Agora podemos partir para a criação do arquivo CSS para personalizar o Swagger UI.


Criando o arquivo CSS

O Swagger UI permite personalização por meio de arquivos CSS estáticos na pasta static dentro de resources. Vamos criar essa estrutura e adicionar um arquivo de estilo para aplicar o tema.

No seu projeto, dentro de src/main/resources, crie uma pasta static (caso ainda não exista) e adicione um arquivo chamado swagger-theme.css.

A estrutura do projeto ficará assim:

├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── swagger_dark/
│   │   │           ├── SwaggerDarkApplication.java
│   │   ├── resources/
│   │   │   ├── application.properties
│   │   │   └── static/
│   │   │       └── swagger-theme.css
Enter fullscreen mode Exit fullscreen mode

Agora que o arquivo swagger-theme.css está no lugar certo, podemos adicionar as regras de estilo para personalizar o Swagger UI.

Deixarei o link do GitHub com o projeto e o CSS aplicado no fim do post.

    .swagger-ui .topbar .download-url-wrapper .select-label select {
        border: 2px solid var(--swagger-color);
    }

    .swagger-ui .info .title small.version-stamp {
        background-color: var(--swagger-color);
    }

    .swagger-ui .info .title small.version-stamp pre {
        color: #3A3D4C;
    }

    .swagger-ui .info a {
        color: var(--link-color);
    }

    .swagger-ui .response-control-media-type--accept-controller select {
        border-color: var(--accept-header-color);
    }

       /*... mais */

Enter fullscreen mode Exit fullscreen mode

Configurando o application.properties ou application.yml:

Para que o Swagger UI consiga carregar corretamente os arquivos estáticos, adicione as seguintes configurações:

application.properties:

spring.mvc.static-path-pattern=/static/**
spring.web.resources.static-locations=classpath:/static/
Enter fullscreen mode Exit fullscreen mode

application.yaml:

spring:
  mvc:
    static-path-pattern: /static/**
  web:
    resources:
      static-locations: classpath:/static/

Enter fullscreen mode Exit fullscreen mode

Isso garante que o Spring Boot consiga servir os arquivos dentro da pasta static corretamente.


Configurando a Injeção do CSS no Swagger UI

Para aplicar o CSS customizado ao Swagger UI, criaremos uma pasta chamada swagger dentro do pacote principal e adicionaremos dois arquivos:

  1. SwaggerConfig.java → Define um Bean para que o Spring reconheça a configuração do Swagger.
  2. SwaggerCustomCssInjector.java → Modifica a página inicial do Swagger UI e injeta nosso CSS.

SwaggerConfig.java:
Este arquivo configura o Bean responsável por inicializar a customização do Swagger.

package com.swagger_dark.swagger_dark.swagger;

import org.springdoc.core.properties.SwaggerUiConfigProperties;
import org.springdoc.core.properties.SwaggerUiOAuthProperties;
import org.springdoc.core.providers.ObjectMapperProvider;
import org.springdoc.webmvc.ui.SwaggerIndexTransformer;
import org.springdoc.webmvc.ui.SwaggerWelcomeCommon;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SwaggerConfig {

  @Bean
  public SwaggerIndexTransformer swaggerIndexTransformer(
    SwaggerUiConfigProperties swaggerUiConfig,
    SwaggerUiOAuthProperties swaggerUiOAuthProperties,
    SwaggerWelcomeCommon swaggerWelcomeCommon,
    ObjectMapperProvider objectMapperProvider) {

    return new SwaggerCustomCssInjector(swaggerUiConfig, swaggerUiOAuthProperties, swaggerWelcomeCommon, objectMapperProvider);
  }
}
Enter fullscreen mode Exit fullscreen mode

SwaggerCustomCssInjector.java:
Este arquivo é responsável por modificar a página inicial do Swagger UI (index.html) e injetar nosso CSS.

package com.swagger_dark.swagger_dark.swagger;

import jakarta.servlet.http.HttpServletRequest;
import org.springdoc.core.properties.SwaggerUiConfigProperties;
import org.springdoc.core.properties.SwaggerUiOAuthProperties;
import org.springdoc.core.providers.ObjectMapperProvider;
import org.springdoc.webmvc.ui.SwaggerIndexPageTransformer;
import org.springdoc.webmvc.ui.SwaggerWelcomeCommon;
import org.springframework.core.io.Resource;
import org.springframework.lang.NonNull;
import org.springframework.web.servlet.resource.ResourceTransformerChain;
import org.springframework.web.servlet.resource.TransformedResource;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

public class SwaggerCustomCssInjector extends SwaggerIndexPageTransformer {
  public SwaggerCustomCssInjector(
    final SwaggerUiConfigProperties swaggerUiConfig,
    final SwaggerUiOAuthProperties swaggerUiOAuthProperties,
    final SwaggerWelcomeCommon swaggerWelcomeCommon,
    final ObjectMapperProvider objectMapperProvider) {
    super(swaggerUiConfig, swaggerUiOAuthProperties, swaggerWelcomeCommon, objectMapperProvider);
  }

  @Override
  public @NonNull Resource transform(
    @NonNull HttpServletRequest request,
    @NonNull Resource resource,
    @NonNull ResourceTransformerChain transformer) throws IOException {
    if ("index.html".equals(resource.getFilename())) {
      try (InputStream in = resource.getInputStream();
           BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
        String html = reader.lines().collect(Collectors.joining(System.lineSeparator()));
        String transformedHtml = injectCss(html);
        return new TransformedResource(resource, transformedHtml.getBytes());
      }
    }
    return super.transform(request, resource, transformer);
  }

  private String injectCss(String html) {
    String cssPath = "/static/swagger-theme.css";
    return html.replace("</head>", "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + cssPath + "\" /></head>");
  }
}
Enter fullscreen mode Exit fullscreen mode

No fim temos a seguinte estrutura:

Diretório:
└── swagger-dartk-spring-boot/
    ├── mvnw
    ├── mvnw.cmd
    ├── pom.xml
    ├── src/
    │   ├── main/
    │   │   ├── java/
    │   │   │   └── com/
    │   │   │       └── swagger_dark/
    │   │   │           └── swagger_dark/
    │   │   │               ├── SwaggerDarkApplication.java
    │   │   │               ├── exemple/
    │   │   │               │   ├── ExampleController.java
    │   │   │               │   └── ExampleDTO.java
    │   │   │               └── swagger/
    │   │   │                   ├── SwaggerConfig.java
    │   │   │                   └── SwaggerCustomCssInjector.java
    │   │   └── resources/
    │   │       ├── application.properties
    │   │       └── static/
    │   │           └── swagger-theme.css
    │   └── test/
    │       └── java/
    │           └── com/
    │               └── swagger_dark/
    │                   └── swagger_dark/
    │                       └── SwaggerDarkApplicationTests.java
    └── .mvn/
        └── wrapper/
            └── maven-wrapper.properties
Enter fullscreen mode Exit fullscreen mode

Resultado Final

Após finalizar as configurações, adicionei alguns endpoints e iniciei o projeto. Agora, o tema está aplicado conforme as modificações feitas no CSS:

Swagger com tema modificado

Com essas configurações, o Swagger UI agora carregará automaticamente o arquivo swagger-theme.css, permitindo personalizar seu visual.

Agora sua API não apenas está documentada e testável, mas também personalizada para refletir a identidade visual do seu projeto. Você pode explorar outras customizações no Swagger UI, como a modificação de fontes, ícones e até mesmo a inclusão de novas funcionalidades com JavaScript.

Para conferir o código completo e as configurações, acesse o repositório no GitHub:

Swagger-dartk-spring-boot

Top comments (0)