A comprehensive CodeIgniter4 API serving Serbian words, names, and surnames with Latin/Cyrillic transliteration support
/api/words
Get paginated list of Serbian words with filtering options
/api/names
Get Serbian names with gender information and vocative forms
/api/surnames
Get Serbian surnames with Latin/Cyrillic variants
/api/transliterate
Convert text between Latin and Cyrillic scripts
/api/random
Get random entry from any dataset type
Generate random Serbian words for language learning apps
/api/random?type=word
Validate Serbian names and get their vocative forms
/api/names/Miloš
Search words by prefix for autocomplete features
/api/words?starts_with=pre&limit=10
Convert text between Latin and Cyrillic scripts
/api/transliterate?text=Zdravo&to=cyrillic
// Fetch random Serbian word
async function getRandomWord() {
try {
const response = await fetch('https://ivanzarkovic.xyz/api/random?type=word');
const data = await response.json();
console.log('Random word:', data.data.word);
console.log('Cyrillic:', data.data.cyrillic);
console.log('Length:', data.data.length);
} catch (error) {
console.error('Error:', error);
}
}
// Search words by prefix
async function searchWords(prefix, limit = 10) {
const url = `https://ivanzarkovic.xyz/api/words?starts_with=${prefix}&limit=${limit}`;
const response = await fetch(url);
const data = await response.json();
return data.data; // Array of words
}
import requests
import json
class SerbianDictionaryAPI:
def __init__(self, base_url='https://ivanzarkovic.xyz/'):
self.base_url = base_url.rstrip('/')
def get_random_word(self, word_type='word'):
"""Get random Serbian word or name"""
url = f"{self.base_url}/api/random"
params = {'type': word_type}
response = requests.get(url, params=params)
response.raise_for_status()
return response.json()['data']
def search_words(self, starts_with=None, contains=None, limit=50):
"""Search words with various filters"""
url = f"{self.base_url}/api/words"
params = {'limit': limit}
if starts_with:
params['starts_with'] = starts_with
if contains:
params['contains'] = contains
response = requests.get(url, params=params)
response.raise_for_status()
return response.json()['data']
def transliterate(self, text, to_script='cyrillic'):
"""Transliterate text between Latin and Cyrillic"""
url = f"{self.base_url}/api/transliterate"
params = {'text': text, 'to': to_script}
response = requests.get(url, params=params)
response.raise_for_status()
return response.json()['data']['transliterated']
# Example usage
api = SerbianDictionaryAPI()
# Get random word
random_word = api.get_random_word()
print(f"Random word: {random_word['word']} ({random_word['cyrillic']})")
# Search words starting with 'pre'
words = api.search_words(starts_with='pre', limit=5)
for word in words:
print(f"{word['word']} -> {word['cyrillic']}")
# Transliterate text
cyrillic_text = api.transliterate("Zdravo, svete!", "cyrillic")
print(f"Cyrillic: {cyrillic_text}")
<?php
class SerbianDictionaryAPI {
private $baseUrl;
public function __construct($baseUrl = 'https://ivanzarkovic.xyz/') {
$this->baseUrl = rtrim($baseUrl, '/');
}
public function getSerbianNames($gender = 'all', $withVocative = true, $limit = 100) {
$url = $this->baseUrl . '/api/names';
$params = [
'gender' => $gender,
'with_vocative' => $withVocative ? 'true' : 'false',
'limit' => $limit
];
$response = $this->makeRequest($url, $params);
return $response['data'];
}
public function searchSurnames($startsWith = null, $limit = 100) {
$url = $this->baseUrl . '/api/surnames';
$params = ['limit' => $limit];
if ($startsWith) {
$params['starts_with'] = $startsWith;
}
$response = $this->makeRequest($url, $params);
return $response['data'];
}
private function makeRequest($url, $params = []) {
$queryString = http_build_query($params);
$fullUrl = $url . '?' . $queryString;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $fullUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("API request failed with status $httpCode");
}
return json_decode($response, true);
}
}
// Example usage
$api = new SerbianDictionaryAPI();
try {
$maleNames = $api->getSerbianNames('male', true, 10);
foreach ($maleNames as $name) {
echo "{$name['name']} ({$name['cyrillic']})\n";
echo "Vocative: {$name['vocative']}\n\n";
}
$surnames = $api->searchSurnames('P', 5);
echo "Surnames starting with 'P':\n";
foreach ($surnames as $surname) {
echo "- {$surname['surname']} ({$surname['cyrillic']})\n";
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
?>
require 'net/http'
require 'json'
require 'uri'
class SerbianDictionaryAPI
def initialize(base_url = 'https://ivanzarkovic.xyz/')
@base_url = base_url.chomp('/')
end
def random_word(type: 'word')
params = { type: type }
response = make_request('/api/random', params)
response['data']
end
def search_words(starts_with: nil, contains: nil, length: nil, limit: 50)
params = { limit: limit }
params[:starts_with] = starts_with if starts_with
params[:contains] = contains if contains
params[:length] = length if length
response = make_request('/api/words', params)
response['data']
end
def transliterate(text, to: 'cyrillic')
params = { text: text, to: to }
response = make_request('/api/transliterate', params)
response['data']['transliterated']
end
def names(gender: 'all', with_vocative: true, limit: 100)
params = {
gender: gender,
with_vocative: with_vocative,
limit: limit
}
response = make_request('/api/names', params)
response['data']
end
private
def make_request(endpoint, params = {})
uri = URI("#{@base_url}#{endpoint}")
uri.query = URI.encode_www_form(params) unless params.empty?
response = Net::HTTP.get_response(uri)
unless response.is_a?(Net::HTTPSuccess)
raise "API request failed: #{response.code} #{response.message}"
end
JSON.parse(response.body)
end
end
# Example usage
api = SerbianDictionaryAPI.new
# Get random word
random_word = api.random_word
puts "Random word: #{random_word['word']} (#{random_word['cyrillic']})"
puts "Length: #{random_word['length']} characters"
# Search for words containing 'grad'
words = api.search_words(contains: 'grad', limit: 5)
puts "\nWords containing 'grad':"
words.each do |word|
puts "- #{word['word']} -> #{word['cyrillic']}"
end
# Get female names with vocative forms
names = api.names(gender: 'female', with_vocative: true, limit: 3)
puts "\nFemale names with vocative:"
names.each do |name|
puts "#{name['name']} (#{name['cyrillic']}) -> Vocative: #{name['vocative']}"
end
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strconv"
)
type SerbianDictionaryAPI struct {
BaseURL string
}
type APIResponse struct {
Success bool `json:"success"`
Data interface{} `json:"data"`
Message string `json:"message,omitempty"`
}
type Word struct {
Word string `json:"word"`
Cyrillic string `json:"cyrillic"`
Length int `json:"length"`
}
type Name struct {
Name string `json:"name"`
Cyrillic string `json:"cyrillic"`
Vocative string `json:"vocative"`
Gender string `json:"gender"`
}
func NewSerbianDictionaryAPI() *SerbianDictionaryAPI {
return &SerbianDictionaryAPI{
BaseURL: "https://ivanzarkovic.xyz/",
}
}
func (api *SerbianDictionaryAPI) GetRandomWord(wordType string) (*Word, error) {
params := url.Values{}
params.Add("type", wordType)
var response APIResponse
err := api.makeRequest("/api/random", params, &response)
if err != nil {
return nil, err
}
wordData, _ := json.Marshal(response.Data)
var word Word
json.Unmarshal(wordData, &word)
return &word, nil
}
func (api *SerbianDictionaryAPI) SearchWords(startsWith string, limit int) ([]Word, error) {
params := url.Values{}
if startsWith != "" {
params.Add("starts_with", startsWith)
}
params.Add("limit", strconv.Itoa(limit))
var response APIResponse
err := api.makeRequest("/api/words", params, &response)
if err != nil {
return nil, err
}
wordsData, _ := json.Marshal(response.Data)
var words []Word
json.Unmarshal(wordsData, &words)
return words, nil
}
func (api *SerbianDictionaryAPI) GetNames(gender string, withVocative bool, limit int) ([]Name, error) {
params := url.Values{}
params.Add("gender", gender)
params.Add("with_vocative", strconv.FormatBool(withVocative))
params.Add("limit", strconv.Itoa(limit))
var response APIResponse
err := api.makeRequest("/api/names", params, &response)
if err != nil {
return nil, err
}
namesData, _ := json.Marshal(response.Data)
var names []Name
json.Unmarshal(namesData, &names)
return names, nil
}
func (api *SerbianDictionaryAPI) makeRequest(endpoint string, params url.Values, result interface{}) error {
fullURL := api.BaseURL + endpoint
if len(params) > 0 {
fullURL += "?" + params.Encode()
}
resp, err := http.Get(fullURL)
if err != nil {
return err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
return json.Unmarshal(body, result)
}
func main() {
api := NewSerbianDictionaryAPI()
// Get random word
word, err := api.GetRandomWord("word")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Random word: %s (%s) - Length: %d\n",
word.Word, word.Cyrillic, word.Length)
// Search words
words, err := api.SearchWords("pre", 5)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Println("\nWords starting with 'pre':")
for _, w := range words {
fmt.Printf("- %s -> %s\n", w.Word, w.Cyrillic)
}
// Get names
names, err := api.GetNames("male", true, 3)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Println("\nMale names with vocative:")
for _, name := range names {
fmt.Printf("%s (%s) -> Vocative: %s\n",
name.Name, name.Cyrillic, name.Vocative)
}
}
# Get random word
curl "https://ivanzarkovic.xyz/api/random?type=word"
# Search words starting with 'pre'
curl "https://ivanzarkovic.xyz/api/words?starts_with=pre&limit=5"
# Get male names with vocative forms
curl "https://ivanzarkovic.xyz/api/names?gender=male&with_vocative=true&limit=10"
# Transliterate text to Cyrillic
curl "https://ivanzarkovic.xyz/api/transliterate?text=Zdravo%20svete&to=cyrillic"
# Get specific word details
curl "https://ivanzarkovic.xyz/api/words/čovek"
# Search words by length
curl "https://ivanzarkovic.xyz/api/words?length=5&limit=10"
# Get surnames starting with specific letter
curl "https://ivanzarkovic.xyz/api/surnames?starts_with=M&limit=15"
# Get statistics
curl "https://ivanzarkovic.xyz/api/stats"