REST API’lerde Girdi Doğrulama

15 Aralık 20244 dk okuma

REST API’lerde Girdi Doğrulama

REST API’lerde girdi doğrulama, güvenli ve sağlam web servisleri oluşturmak için çok önemlidir. Bu makalede, Spring Boot kullanarak Java ve Kotlin’de, Gin framework’ü ile Go’da doğrulamanın nasıl yapılacağını adım adım inceleyeceğiz.


🌟 Girdi Doğrulama Neden Önemlidir?

Doğrulama, API’nıza gönderilen verilerin beklenen formatlara uygun olmasını sağlayarak SQL Enjeksiyonu, XSS ve hatalı veri girişi gibi potansiyel güvenlik açıklarını engeller.


🛠️ 1. Adım: Doğrulama Bağımlılıklarını Ekleyin

Spring Boot Projeleri için:

  • Maven:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
  • Gradle:
implementation 'org.springframework.boot:spring-boot-starter-validation'

Gin Framework (Go) için:

# Gin frameworkünü yükleyin go get -u github.com/gin-gonic/gin # Doğrulama paketi ekleyin go get -u github.com/go-playground/validator/v10

📖 2. Adım: Doğrulama Kuralları ile Bir DTO Tanımlayın

Alanlara doğrulama kurallarını tanımlamak için anotasyonlar kullanın. Örnekler: @NotNull, @Size, @Pattern.

package com.example.demo.dto; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.Data; @Data public class TodoRequest { @NotNull(message = "Başlık zorunludur") @Size(min = 3, max = 50, message = "Başlık 3 ile 50 karakter arasında olmalıdır") private String title; private boolean completed; }
package com.example.demo.dto import jakarta.validation.constraints.NotNull import jakarta.validation.constraints.Size data class TodoRequest( @field:NotNull(message = "Başlık zorunludur") @field:Size(min = 3, max = 50, message = "Başlık 3 ile 50 karakter arasında olmalıdır") val title: String?, val completed: Boolean = false )
package dto import ( "github.com/go-playground/validator/v10" ) type TodoRequest struct { Title string `validate:"required,min=3,max=50"` Completed bool `validate:""` } var validate = validator.New() func ValidateTodoRequest(todo TodoRequest) error { return validate.Struct(todo) }

📘 3. Adım: Doğrulama ile Bir Controller Oluşturun

Doğrulamayı REST endpoint’lerinize entegre edin.

package com.example.demo.controller; import com.example.demo.dto.TodoRequest; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/todos") public class TodoController { @PostMapping public String createTodo(@Validated @RequestBody TodoRequest request) { return "Oluşturulan görev: " + request.getTitle(); } }
package com.example.demo.controller import com.example.demo.dto.TodoRequest import org.springframework.validation.annotation.Validated import org.springframework.web.bind.annotation.* @RestController @RequestMapping("/api/todos") class TodoController { @PostMapping fun createTodo(@Validated @RequestBody request: TodoRequest): String { return "Oluşturulan görev: ${request.title}" } }
package controller import ( "dto" "github.com/gin-gonic/gin" "net/http" ) func CreateTodoHandler(c *gin.Context) { var todo dto.TodoRequest if err := c.ShouldBindJSON(&todo); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := dto.ValidateTodoRequest(todo); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Oluşturulan görev", "title": todo.Title}) }

📋 4. Adım: Hata Mesajlarını Yönetin

Hata mesajlarını daha kullanıcı dostu olacak şekilde düzelleyin.

package com.example.demo.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.MethodArgumentNotValidException; import java.util.HashMap; import java.util.Map; @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) { Map<String, String> errors = new HashMap<>(); ex.getBindingResult().getFieldErrors().forEach(error -> errors.put(error.getField(), error.getDefaultMessage())); return errors; } }
package com.example.demo.exception import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.ExceptionHandler import org.springframework.web.bind.annotation.RestControllerAdvice import org.springframework.web.bind.MethodArgumentNotValidException @RestControllerAdvice class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException::class) fun handleValidationExceptions(ex: MethodArgumentNotValidException): Map<String, String> { return ex.bindingResult.fieldErrors.associate { it.field to it.defaultMessage.orEmpty() } } }
package middleware import ( "github.com/gin-gonic/gin" "net/http" ) func ErrorHandler() gin.HandlerFunc { return func(c *gin.Context) { c.Next() if len(c.Errors) > 0 { c.JSON(http.StatusBadRequest, gin.H{"errors": c.Errors.JSON()}) } } }

🌐 main.go Örneği

Gin uygulaması için main.go dosyasının bir örneği:

package main import ( "controller" "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.POST("/api/todos", controller.CreateTodoHandler) r.Run() // Sunucu: http://localhost:8080 }

▶️ 5. Adım: Uygulamayı Çalıştırın

Spring Boot (Java/Kotlin)

Spring Boot uygulamasını terminal veya IDE’nizden çalıştırın:

./mvnw spring-boot:run # Maven projeleri için ./gradlew bootRun # Gradle projeleri için

API adresi: http://localhost:8080/api/todos

Gin (Go)

Go uygulamasını çalıştırın:

go run main.go

API adresi: http://localhost:8080/api/todos


🧪 cURL ile Test Etme

API’yı test etmek için cURL komutları:

  • Yeni Bir Görev Ekleme:
curl -X POST http://localhost:8080/api/todos \ -H "Content-Type: application/json" \ -d '{"title": "Yeni Görev", "completed": false}'
  • Tüm Görevleri Getirme:
curl -X GET http://localhost:8080/api/todos
  • Doğrulama Hatalarını Test Etme:

Geçersiz bir istek gönderin:

curl -X POST http://localhost:8080/api/todos \ -H "Content-Type: application/json" \ -d '{"title": ""}'

Bu, doğrulama hata mesajlarını içeren bir yanıt döndürecektir.