KNETRequestSnapshot pozwala zapisywa膰 requesty i odpowiedzi
do p贸藕niejszego u偶ycia - debugging, testowanie, dokumentacja, eksport do narz臋dzi zewn臋trznych.
import rip.nerd.kitsunenet.util.KNETRequestSnapshot
// Utw贸rz manager snapshot贸w
val snapshot = KNETRequestSnapshot()
// Wykonaj request
val request = KNETRequest.get("https://api.example.com/users/1")
val response = client.request(request)
// Zapisz snapshot
snapshot.save(
id = "users/get-single",
request = request,
response = response,
tags = listOf("users", "read"),
notes = "Pobiera pojedynczego u偶ytkownika po ID"
)
// P贸藕niej - przywr贸膰 snapshot
val restored = snapshot.restore("users/get-single")
println("URL: ${restored?.request?.url}")
println("Status: ${restored?.response?.statusCode}")
data class Snapshot(
val id: String, // Unikalny identyfikator
val request: KNETRequest, // Zapisany request
val response: KNETResponse?, // Zapisana odpowied藕 (opcjonalna)
val timestamp: Long, // Kiedy utworzono
val tags: List<String>, // Tagi do grupowania
val notes: String? // Notatki
) {
val group: String? // Grupa (cz臋艣膰 przed "/")
val name: String // Nazwa (cz臋艣膰 po "/")
}
// U偶yj "/" do grupowania
"auth/login" // group="auth", name="login"
"auth/logout" // group="auth", name="logout"
"users/list" // group="users", name="list"
"users/create" // group="users", name="create"
"orders/get-by-id" // group="orders", name="get-by-id"
// Bez grupy
"simple-request" // group=null, name="simple-request"
save()Zapisuje snapshot.
fun save(
id: String,
request: KNETRequest,
response: KNETResponse? = null,
tags: List<String> = emptyList(),
notes: String? = null
): Snapshot
// Zapisz tylko request
snapshot.save("templates/post-user", request)
// Zapisz request z odpowiedzi膮
snapshot.save("api/get-users", request, response)
// Z pe艂n膮 metadat膮
snapshot.save(
id = "auth/login-success",
request = request,
response = response,
tags = listOf("auth", "critical", "happy-path"),
notes = "Poprawne logowanie z valid credentials"
)
restore()Przywraca snapshot po ID.
fun restore(id: String): Snapshot?
restoreRequest()Przywraca tylko request.
fun restoreRequest(id: String): KNETRequest?
restoreResponse()Przywraca tylko response.
fun restoreResponse(id: String): KNETResponse?
// Przywr贸膰 i wykonaj ponownie
val savedRequest = snapshot.restoreRequest("users/create")
if (savedRequest != null) {
// Wykonaj ten sam request ponownie
val newResponse = client.request(savedRequest)
println("Nowa odpowied藕: ${newResponse.statusCode}")
}
getAll()Pobiera wszystkie snapshoty.
fun getAll(): List<Snapshot>
getByGroup()Pobiera snapshoty z danej grupy.
fun getByGroup(group: String): List<Snapshot>
// Pobierz wszystkie snapshoty autoryzacji
val authSnapshots = snapshot.getByGroup("auth")
authSnapshots.forEach { snap ->
println("${snap.name}: ${snap.request.method} ${snap.request.url}")
}
// Output:
// login: POST https://api.example.com/auth/login
// logout: POST https://api.example.com/auth/logout
// refresh: POST https://api.example.com/auth/refresh
getByTag()Pobiera snapshoty z danym tagiem.
fun getByTag(tag: String): List<Snapshot>
// Pobierz wszystkie krytyczne snapshoty
val criticalSnapshots = snapshot.getByTag("critical")
// Pobierz wszystkie b艂臋dne scenariusze
val errorSnapshots = snapshot.getByTag("error-case")
search()Wyszukuje snapshoty po tek艣cie.
fun search(query: String): List<Snapshot>
// Szukaj w ID, URL i notatkach
val results = snapshot.search("users")
results.forEach { snap ->
println("${snap.id}: ${snap.request.url}")
}
delete() / clear()fun delete(id: String): Boolean // Usu艅 jeden
fun clear() // Usu艅 wszystkie
exportToJson() / importFromJson()Eksport/import do formatu JSON.
val json = snapshot.exportToJson()
println(json)
// {
// "version": "1.0",
// "exportedAt": "2024-01-15T10:30:00Z",
// "snapshots": [...]
// }
// Import
val imported = snapshot.importFromJson(json)
println("Zaimportowano $imported snapshot贸w")
saveToFile() / loadFromFile()Zapis/odczyt z pliku.
// Zapisz do pliku
snapshot.saveToFile(File(context.filesDir, "snapshots.json"))
// Wczytaj z pliku
val loaded = snapshot.loadFromFile(File(context.filesDir, "snapshots.json"))
println("Wczytano $loaded snapshot贸w")
exportToCurl()Eksport do polece艅 cURL.
val curlCommands = snapshot.exportToCurl()
println(curlCommands)
curl -X POST 'https://api.example.com/users' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer token123' \
-d '{"name":"Jan","email":"jan@example.com"}'
curl 'https://api.example.com/users/1' \
-H 'Authorization: Bearer token123'
exportToPostman()Eksport do formatu Postman Collection v2.1.
fun exportToPostman(collectionName: String = "KNET Snapshots"): String
// Eksportuj do Postman
val postmanJson = snapshot.exportToPostman("My API Collection")
// Zapisz do pliku
File("postman_collection.json").writeText(postmanJson)
// Teraz mo偶esz zaimportowa膰 ten plik do Postman:
// Postman -> Import -> Upload Files -> wybierz plik
val stats = snapshot.getStats()
println("Snapshoty: ${stats["totalSnapshots"]}")
println("Grupy: ${stats["groups"]}")
println("Tagi: ${stats["tags"]}")
println("Metody: ${stats["byMethod"]}")
println("Z odpowiedzi膮: ${stats["withResponse"]}")
println("Bez odpowiedzi: ${stats["withoutResponse"]}")
Snapshoty: 15
Grupy: [auth, users, orders]
Tagi: [critical, read, write, error-case]
Metody: {GET=8, POST=5, PUT=1, DELETE=1}
Z odpowiedzi膮: 12
Bez odpowiedzi: 3
class DebugApiClient(private val client: KNETClient) {
private val snapshot = KNETRequestSnapshot()
suspend fun request(request: KNETRequest): KNETResponse {
val response = client.request(request)
// Zapisz b艂臋dne requesty do analizy
if (!response.isSuccessful) {
snapshot.save(
id = "errors/${System.currentTimeMillis()}",
request = request,
response = response,
tags = listOf("error", "debug", "status-${response.statusCode}"),
notes = "B艂膮d: ${response.statusCode} ${response.statusMessage}"
)
}
return response
}
fun exportErrors(): String {
val errors = snapshot.getByTag("error")
return errors.map { it.toMap() }.toString()
}
}
class ApiDocumentor {
private val snapshot = KNETRequestSnapshot()
fun documentEndpoint(
name: String,
description: String,
request: KNETRequest,
response: KNETResponse
) {
snapshot.save(
id = "docs/$name",
request = request,
response = response,
tags = listOf("documentation"),
notes = description
)
}
fun generateDocumentation() {
val docs = snapshot.getByTag("documentation")
docs.forEach { doc ->
println("## ${doc.name}")
println(doc.notes)
println()
println("**Request:**")
println("```")
println("${doc.request.method} ${doc.request.url}")
doc.request.headers.forEach { (k, v) -> println("$k: $v") }
println("```")
println()
println("**Response:** ${doc.response?.statusCode}")
println()
}
}
fun exportToPostman() = snapshot.exportToPostman("API Documentation")
}
// U偶ycie
val documenter = ApiDocumentor()
// Dokumentuj ka偶dy endpoint
documenter.documentEndpoint(
name = "get-user",
description = "Pobiera u偶ytkownika po ID. Wymaga autoryzacji Bearer token.",
request = KNETRequest.get("https://api.example.com/users/123"),
response = response
)
// Eksportuj do Postman
val postmanCollection = documenter.exportToPostman()
class TestFixtures {
companion object {
private val snapshot = KNETRequestSnapshot()
init {
// Wczytaj fixtures z pliku
val fixturesFile = File("src/test/resources/fixtures.json")
if (fixturesFile.exists()) {
snapshot.loadFromFile(fixturesFile)
}
}
fun getLoginRequest(): KNETRequest {
return snapshot.restoreRequest("fixtures/login")
?: throw IllegalStateException("Missing fixture: fixtures/login")
}
fun getExpectedUserResponse(): KNETResponse {
return snapshot.restoreResponse("fixtures/get-user")
?: throw IllegalStateException("Missing fixture: fixtures/get-user")
}
}
}
// W testach
class UserApiTest {
@Test
fun `should login successfully`() = runTest {
val request = TestFixtures.getLoginRequest()
val response = client.request(request)
assertEquals(200, response.statusCode)
}
}
// Sklonuj istniej膮cy snapshot z nowym ID
snapshot.clone("users/create", "users/create-v2")
// Przywr贸膰, zmodyfikuj i zapisz
val original = snapshot.restoreRequest("users/create")!!
val modified = original.copy(
url = original.url.replace("/users", "/v2/users"),
headers = original.headers + ("X-Version" to "2")
)
snapshot.save("users/create-v2", modified)
class SnapshotViewModel : ViewModel() {
private val snapshot = KNETRequestSnapshot()
private val _snapshots = MutableStateFlow<List<Snapshot>>(emptyList())
val snapshots = _snapshots.asStateFlow()
init {
loadSnapshots()
}
private fun loadSnapshots() {
_snapshots.value = snapshot.getAll()
}
fun saveRequest(id: String, request: KNETRequest, response: KNETResponse?) {
snapshot.save(id, request, response)
loadSnapshots()
}
fun deleteSnapshot(id: String) {
snapshot.delete(id)
loadSnapshots()
}
fun exportAll(): String {
return snapshot.exportToJson()
}
fun shareAsPostman(): String {
return snapshot.exportToPostman("Moje Snapshoty")
}
}