# Implement your own

By providing different HTTP client implementations that already fulfill the need of [having good old Http requests](/docs/http-client/fetchers/httpfetcher.md), [imitating a browser by executing Javascript](/docs/http-client/fetchers/browserfetcher.md) and [doing async http calls](/docs/http-client/fetchers/asyncfetcher.md) you probably have special requirements that are hard to meet using the provided client implementations but on the other hand you still want to use the full skrape{it} DSL experience.

All the Fetchers are implementing either [BlockingFetcher or a NonBlockingFetcher](https://github.com/skrapeit/skrape.it/blob/master/fetcher/base-fetcher/src/main/kotlin/it/skrape/fetcher/BaseFetcher.kt) which are interfaces provided by the skrape{it} library. Both of them wants to have an implementation of a fetch method and requestBuilder.

In the example we implement a BlockingFetcher that can be passed to the skrape{it} DSL that is using Ktors different HttpClient implementations under the hood.

{% code title="implement custom fetcher" %}

```kotlin
class KtorBlockingFetcher(val ktorClient: HttpClient) : BlockingFetcher<HttpRequestBuilder> {
    
    override fun fetch(request: HttpRequestBuilder): Result = runBlocking { // runBlocking because ktor is fully build on coroutines but in our example we want it blocking
        with(ktorClient.request<HttpResponse>(request)) { // do http call with ktor client
            Result( // map ktor result to skrape{it} result
                responseBody = readText(),
                responseStatus = Result.Status(status.value, status.description),
                contentType = contentType()?.toString(),
                headers = headers.toMap().mapValues { it.value.firstOrNull().orEmpty() },
                baseUri = request.url.toString(),
                cookies = listOf(setCookie()) as List<Cookie>
            )
        }
    }

    override val requestBuilder: HttpRequestBuilder
        get() = HttpRequestBuilder()
}
```

{% endcode %}

{% code title="use custom fetcher" %}

```kotlin
val KTOR_CLIENT = HttpClient(Apache)

val result = skrape(KtorBlockingFetcher(KTOR_CLIENT)) {
    request {
        url = "http://some.url"
    }

    response {
        // do your stuff here
    }
}
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.skrape.it/docs/http-client/fetchers/implement-your-own.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
