Vala를 사용하여 DEV.to API 강화

23121 단어 valashowdevtutorial
Vala이 미래의 언어라는 말은 아닙니다. 내가 말하는 것은 훌륭한 앱이 내장되어 있다는 것입니다.

ThiefMD 1은 최근 DEV.to에 게시하기 위한 지원을 추가했습니다. ThiefMD는 Vala을 사용하여 이 작업을 수행하며 오늘 그 방법을 보여드리고자 합니다.



DEV API은 잘 문서화되어 있습니다. 이 게시물은 Valavangelism(훌륭한 언어입니다)에 관한 것입니다. 네트워크를 통한 API 호출의 경우 Vala에는 cURLlibsoup 2 모두에 대한 바인딩이 있습니다. libsoup는 Vala's Main Loop과 통합되며 좋은API 을 가지고 있습니다. libsoup +json-glib는 REST API와 상호 작용할 수 있는 재미있고 친근한 방법을 제공합니다.

전제 조건



나는 우분투 22.04에 있습니다. 종속성의 경우 다음을 실행합니다.

sudo apt install build-essential valac libsoup2.4-dev libjson-glib-dev meson ninja-build


WebCall 추상화



REST API 호출을 수행하기 위해 Soup.SessionSoup.Message 생성을 래핑하는 클래스를 만들었습니다.

/**
 * WebCall wraps a Soup.Session and handles managing Soup Messages
 */
private class WebCall {
    private Soup.Session session;
    private Soup.Message message;
    private string url;
    private string body;
    private bool is_mime = false;

    public string response_str;
    public uint response_code;

    /**
      * Constructs a Soup.Session for the given endpoint
      * 
      * @param endpoint The URL to connect to
      * @param api The path the API rests at
      */
    public class WebCall (string endpoint, string api) {
        url = endpoint + api;
        session = new Soup.Session ();
        body = "";
    }

    /**
      * Sets the data body for this request
      * 
      * @param data The data to populate the body with
      */
    public void set_body (string data) {
        body = data;
    }

    /**
      * Constructs a GET Soup.Message for this session
      */
    public void set_get () {
        message = new Soup.Message ("GET", url);
    }

    /**
      * Constructs a DELETE Soup.Message for this session
      */
    public void set_delete () {
        message = new Soup.Message ("DELETE", url);
    }

    /**
      * Constructs a POST Soup.Message for this session
      */
    public void set_post () {
        message = new Soup.Message ("POST", url);
    }

    /**
      * Adds an HTTP header to the current Soup.Message
      * 
      * @param key The HTTP Header Key to add
      * @param value The value for the HTTP Header
      */
    public void add_header (string key, string value) {
        message.request_headers.append (key, value);
    }

    /**
      * Performs the Session call for the current Message.
      * Returns true if the call receives a success code.
      * Returns false if the call fails or receives empty data.
      */
    public bool perform_call () {
        MainLoop loop = new MainLoop ();
        bool success = false;
        debug ("Calling %s", url);

        // The DEV API requires a User Agent
        add_header ("User-Agent", "Vala-to-Dev/0.1");
        if (body != "") {
            message.set_request ("application/json", Soup.MemoryUse.COPY, body.data);
        }

        session.queue_message (message, (sess, mess) => {
            response_str = (string) mess.response_body.flatten ().data;
            response_code = mess.status_code;

            // Validate we have a string response and success HTTP code
            if (response_str != null && response_str != "" &&
                response_code >= 200 && response_code <= 250)
            {
                success = true;
            }
            loop.quit ();
        });

        loop.run ();
        return success;
    }
}

new WebCall는 Soup.Session을 구성합니다. set_post , set_get 등은 적절한 Soup.Message 유형을 구성합니다. perform_call REST API 호출을 실행합니다. MainLoop loop = new MainLoop ();session.queue_message를 사용하면 백그라운드에서 웹 요청이 발생하는 동안 GUI가 계속 실행되도록 할 수 있습니다.

이 클래스를 사용하면 DEV API와 쉽게 대화할 수 있습니다. JSON-GLib은 DEV API 언어를 구사하는 데 도움이 됩니다.

Vala의 JSON 말하기



쉬운 예로 The authenticated user 을 확인하겠습니다. 샘플 출력은 다음과 같습니다.

{
    "type_of": "user",
    "id": 1234,
    "username": "bob",
    "name": "bob",
    "summary": "Hello, world",
    "twitter_username": "bob",
    "github_username": "bob",
    "website_url": null,
    "location": "New York",
    "joined_at": "Jan 1, 2017",
    "profile_image": "https://res.cloudinary.com/...jpeg"
}


JSON-GLib를 사용하여 개체를 나타내는 클래스는 다음과 같습니다.

public class UserResponse : GLib.Object, Json.Serializable {
    public string type_of { get; set; }
    public int id { get; set; }
    public string username { get; set; }
    public string name { get; set; }
    public string summary { get; set; }
    public string twitter_username { get; set; }
    public string github_username { get; set; }
    public string website_url { get; set; }
    public string location { get; set; }
    public string joined_at { get; set; }
    public string profile_image { get; set; }
}

Json.Serializable를 사용하면 Vala 개체에서 JSON 표현으로 쉽게 이동할 수 있습니다.

API 호출하기



DEV API Key 이 있으면 메시지 전송을 시작할 준비가 된 것입니다. API 키에 대한 유효성 검사는 다음과 같습니다.

/**
 * Retrieves the username corresponding to the API-Key.
 * Returns true if the API Key worked, false otherwise.
 * 
 * @param username Receives the alias associated with the API-Key
 * @param api_key The API KEY to use for authentication
 */
public bool get_authenticated_user (
    out string username,
    string api_key)
{
    // Create a WebCall to handle this session
    WebCall authentication = new WebCall ("https://dev.to", "/api/users/me");
    // The Authentication API expects a GET request
    authentication.set_get ();
    // Add our API Key
    authentication.add_header ("api-key", api_key);

    // Perform our call
    bool res = authentication.perform_call ();
    if (!res) {
        return false;
    }

    // Parse the reponse
    Json.Parser parser = new Json.Parser ();
    parser.load_from_data (authentication.response_str);
    Json.Node data = parser.get_root ();
    UserResponse response = Json.gobject_deserialize (
        typeof (UserResponse),
        data)
        as UserResponse;

    username = response.username;
    return true;
}


팔! 이제 API 키를 확인할 수 있습니다.

createArticle 에 대해 비슷한 작업을 수행할 수 있으며 실제로 수행했습니다! 코드는 github.com/ThiefMD/forem-vala에 있습니다.

감사



친애하는 독자 여러분, 대단하다고 생각합니다. Vala와 함께라면 멋진 작품을 만들 수 있을 것 같아요! 그러니 나가서 건설하고 주저하지 말고 도움을 요청하십시오.



ThiefMD은 이 라이브러리를 사용하여 문서를 DEV로 내보낼 수 있도록 합니다. Spell Checking , 및 Write-Good ThiefMD를 사용하면 선생님의 빨간 펜을 금방 놓칠 수 있습니다. 내 말은, 훌륭한 DEV 기사를 즉시 작성하고 출판한다는 것입니다.



나는 ThiefMD 😻️를 만듭니다.

GLib 또는 GTK를 사용하지 않는 경우 cURL이 더 이식성이 뛰어난 솔루션입니다.

좋은 웹페이지 즐겨찾기