حزم SDK

API مبني على HTTPS وJSON العاديين، لذا يعمل بالفعل من أي لغة. نعمل أيضًا على بناء مكتبة رسمية لكل لغة من اللغات أدناه. كل مكتبة صغيرة عن قصد: عميل محدد الأنواع لنقاط النهاية الثماني، ومهلات زمنية، وإعادة محاولة عند 429 و503، وتأخير معالجة الإدخال للإكمال التلقائي. لا إطار عمل ولا إضافات.

الحالة حسب اللغة

JavaScript وTypeScript قيد التطوير

npm install @mygeocode/sdk

تعمل في Node 18+ وDeno وBun والمتصفحات. تأتي مع تعريفات الأنواع.

Python قيد التطوير

pip install mygeocode

Python 3.9+. عملاء متزامنون وغير متزامنين، دون أي اعتماديات سوى httpx.

PHP مخطط لها

composer require mygeocode/sdk

PHP 8.1+. عميل PSR-18، استخدم مكتبة HTTP التي تفضّلها.

Go مخطط لها

go get github.com/mygeocode/mygeocode-go

المكتبة القياسية فقط. يدعم context.

Java مخطط لها

com.mygeocode:sdk

Java 11+. مبنية على java.net.http، ويمكن استخدامها من Kotlin أيضًا.

C# مخطط لها

dotnet add package MyGeocode

.NET 6+. غير متزامنة بالكامل، مع System.Text.Json.

Ruby مخطط لها

gem install mygeocode

Ruby 3.0+. تستخدم Net::HTTP، دون اعتماديات وقت التشغيل.

Rust مخطط لها

cargo add mygeocode

reqwest وserde، غير متزامنة افتراضيًا.

أوامر التثبيت أعلاه محجوزة وستعمل في يوم إصدار كل مكتبة. هل تريد أن تعرف متى؟ أرسل رسالة بريد إلكتروني فارغة إلى support@mygeocode.com وسنرد مرة واحدة، عندما يتوفر ما يمكن تثبيته.

ما ستفعله كل حزمة SDK

دالة واحدة لكل نقطة نهاية

client.forward("...") وclient.reverse(lat, lon) وclient.ipv4("8.8.8.8") وهكذا. القيم المُعادة سجلات محددة الأنواع تعكس JSON تمامًا، بأسماء الحقول نفسها.

إعادة محاولة تحترم الترويسات

يُعاد إرسال 429 المصحوب بموعد إعادة التصفير بعد ذلك الموعد، حتى حد تضبطه أنت. يُعاد إرسال 503 مع تأخير متزايد. وكل ما عدا ذلك يُطلق كخطأ يحمل code وmessage من API.

التعامل مع المفتاح

مرّر مفتاحًا إلى المُنشئ أو اضبط MYGEOCODE_KEY في متغيرات البيئة. لا يُكتب شيء على القرص. غياب المفتاح يطلق خطأ فورًا مع إشارة إلى لوحة التحكم.

استخدم HTTP API اليوم

إليك ترميزًا جغرافيًا عكسيًا مع معالجة للأخطاء وإعادة محاولة عند 429، باللغات التي ستغطيها أولى حزم SDK. هذا تقريبًا ما ستفعله المكتبات داخليًا.

const BASE = "https://api.mygeocode.com/v1";

async function reverse(lat, lon, { key = process.env.MYGEOCODE_KEY, retries = 2 } = {}) {
  const url = new URL(BASE + "/reverse");
  url.searchParams.set("lat", lat);
  url.searchParams.set("lon", lon);

  const headers = key ? { "X-API-Key": key } : {};
  const res = await fetch(url, { headers });

  if (res.status === 429 && retries > 0) {
    const reset = Number(res.headers.get("X-Quota-Reset")) * 1000;
    const wait = Math.min(Math.max(reset - Date.now(), 1000), 60_000);
    await new Promise((r) => setTimeout(r, wait));
    return reverse(lat, lon, { key, retries: retries - 1 });
  }

  const data = await res.json();
  if (data.status !== "ok") throw new Error(`${data.error.code}: ${data.error.message}`);
  return data.result;
}

const place = await reverse(48.8584, 2.2945);
console.log(place.formatted, place.precision);
import os
import time
import requests

BASE = "https://api.mygeocode.com/v1"


class MyGeocodeError(Exception):
    pass


def reverse(lat, lon, key=os.environ.get("MYGEOCODE_KEY"), retries=2):
    headers = {"X-API-Key": key} if key else {}
    r = requests.get(f"{BASE}/reverse", params={"lat": lat, "lon": lon}, headers=headers, timeout=10)

    if r.status_code == 429 and retries > 0:
        reset = int(r.headers.get("X-Quota-Reset", 0))
        time.sleep(min(max(reset - time.time(), 1), 60))
        return reverse(lat, lon, key=key, retries=retries - 1)

    data = r.json()
    if data["status"] != "ok":
        raise MyGeocodeError(f'{data["error"]["code"]}: {data["error"]["message"]}')
    return data["result"]


place = reverse(48.8584, 2.2945)
print(place["formatted"], place["precision"])
<?php
const BASE = "https://api.mygeocode.com/v1";

function reverse(float $lat, float $lon, ?string $key = null, int $retries = 2): array
{
    $key ??= getenv("MYGEOCODE_KEY") ?: null;
    $ch = curl_init(BASE . "/reverse?" . http_build_query(["lat" => $lat, "lon" => $lon]));
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 10,
        CURLOPT_HTTPHEADER => $key ? ["X-API-Key: $key"] : [],
    ]);
    $body = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    curl_close($ch);

    if ($status === 429 && $retries > 0) {
        sleep(5);
        return reverse($lat, $lon, $key, $retries - 1);
    }

    $data = json_decode($body, true);
    if ($data["status"] !== "ok") {
        throw new RuntimeException($data["error"]["code"] . ": " . $data["error"]["message"]);
    }
    return $data["result"];
}

$place = reverse(48.8584, 2.2945);
echo $place["formatted"], " (", $place["precision"], ")\n";
package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"time"
)

const base = "https://api.mygeocode.com/v1"

type Result struct {
	Formatted string  `json:"formatted"`
	Lat       float64 `json:"lat"`
	Lon       float64 `json:"lon"`
	Precision string  `json:"precision"`
}

type envelope struct {
	Status string  `json:"status"`
	Result *Result `json:"result"`
	Error  *struct {
		Code    string `json:"code"`
		Message string `json:"message"`
	} `json:"error"`
}

func reverse(lat, lon float64, retries int) (*Result, error) {
	q := url.Values{"lat": {strconv.FormatFloat(lat, 'f', -1, 64)}, "lon": {strconv.FormatFloat(lon, 'f', -1, 64)}}
	req, _ := http.NewRequest("GET", base+"/reverse?"+q.Encode(), nil)
	if key := os.Getenv("MYGEOCODE_KEY"); key != "" {
		req.Header.Set("X-API-Key", key)
	}
	resp, err := (&http.Client{Timeout: 10 * time.Second}).Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode == 429 && retries > 0 {
		time.Sleep(5 * time.Second)
		return reverse(lat, lon, retries-1)
	}

	var env envelope
	if err := json.NewDecoder(resp.Body).Decode(&env); err != nil {
		return nil, err
	}
	if env.Status != "ok" {
		return nil, errors.New(env.Error.Code + ": " + env.Error.Message)
	}
	return env.Result, nil
}

func main() {
	place, err := reverse(48.8584, 2.2945, 2)
	if err != nil {
		panic(err)
	}
	fmt.Println(place.Formatted, place.Precision)
}

هل تستخدم حزمة SDK من مزوّد آخر؟

قد لا تحتاج إلى حزمتنا. تقبل مكتبات العملاء الرسمية من Google Maps وBing وHERE وMapbox وipinfo في الغالب عنوان URL أساسيًا مخصصًا، وتجيب المضيفات البديلة المتوافقة لدينا بصيغ هؤلاء المزوّدين. وجّه المكتبة إلى مضيف www.mygeocode.com المطابق واحتفظ بالكود الذي لديك.