{"id":12,"date":"2016-04-27T11:34:28","date_gmt":"2016-04-27T11:34:28","guid":{"rendered":"https:\/\/blogs.scummvm.org\/tkachov\/?p=12"},"modified":"2022-05-24T11:34:52","modified_gmt":"2022-05-24T11:34:52","slug":"gsoc-designing-api","status":"publish","type":"post","link":"https:\/\/blogs.scummvm.org\/tkachov\/2016\/04\/27\/gsoc-designing-api\/","title":{"rendered":"GSoC: Designing API"},"content":{"rendered":"<p>One of\u00a0the most important tasks for my\u00a0project is\u00a0to\u00a0design the API right. That\u2019s something\u00a0I would start with, so\u00a0if\u00a0there are any mistakes or\u00a0wrong decisions, I\u2019d be\u00a0suffering from those later. Of\u00a0course, I\u00a0don\u2019t want to\u00a0suffer or\u00a0rewrite the API over and over again, so\u00a0I should think it\u00a0through.<\/p>\n<p>I\u00a0already mentioned\u00a0I wrote a\u00a0small prototype, which uses Dropbox API and has simple sync feature. I\u00a0actually thought\u00a0I should write prototypes for all cloud providers I\u2019m going to\u00a0add support\u00a0of, so\u00a0I get experience of\u00a0using those. That would help me\u00a0find common parts and differences, and with all this experience\u00a0I would be\u00a0ready to\u00a0design a\u00a0good API\u00a0\u2014 considering all pitfalls\u00a0I met writing prototypes.<\/p>\n<p>But a\u00a0few days back\u00a0I thought that\u00a0I can just imagine an\u00a0\u00abideal\u00bb API: something simple, designed exactly for my\u00a0goal. What do\u00a0I\u00a0need? I\u00a0need listing files, uploading and downloading. OK, I\u00a0also would need deleting, updating modification date and creating directories. And&#8230; that\u2019s it. And, as\u00a0that\u2019s an\u00a0API, I\u00a0don\u2019t care how it\u2019s implemented. I\u00a0care that backend does these operations, no\u00a0matter what it\u00a0does in\u00a0order to\u00a0do\u00a0these. (Even though it\u2019s me\u00a0who will be\u00a0writing these backends.)<\/p>\n<p>I\u00a0still would study Google Drive and OneDrive APIs, and may be\u00a0I\u2019ll get some free time in\u00a0order to\u00a0write prototypes for those too. But for now I\u2019ve designed two simple sketches I\u2019ve shown to\u00a0my\u00a0mentor, Peter Bozs\u00f3 (uruk-hai), and Eugene Sandulenko (sev).<\/p>\n<p>First one is\u00a0quite similar to\u00a0what I\u2019m using in\u00a0my\u00a0prototype:<\/p>\n<pre class=\"sh_c sh_sourceCode\">file <span class=\"sh_cbracket\">{<\/span>\r\n    path\r\n    name\r\n    size\r\n    timestamp\r\n    is_directory\r\n<span class=\"sh_cbracket\">}<\/span>\r\n\r\nservice <span class=\"sh_cbracket\">{<\/span>\r\n    file<span class=\"sh_symbol\">[]<\/span> <span class=\"sh_function\">list_directory<\/span><span class=\"sh_symbol\">(<\/span>path<span class=\"sh_symbol\">)<\/span>\r\n    <span class=\"sh_type\">bool<\/span> <span class=\"sh_function\">upload<\/span><span class=\"sh_symbol\">(<\/span>path<span class=\"sh_symbol\">,<\/span> file_contents<span class=\"sh_symbol\">)<\/span>    <span class=\"sh_comment\">\/\/may be \"save\"<\/span>\r\n    <span class=\"sh_usertype\">file_contents<\/span> <span class=\"sh_function\">download<\/span><span class=\"sh_symbol\">(<\/span>path<span class=\"sh_symbol\">)<\/span>        <span class=\"sh_comment\">\/\/may be \"read\"<\/span>\r\n    <span class=\"sh_type\">bool<\/span> <span class=\"sh_function\">delete<\/span><span class=\"sh_symbol\">(<\/span>path<span class=\"sh_symbol\">)<\/span>\r\n    <span class=\"sh_type\">bool<\/span> <span class=\"sh_function\">sync<\/span><span class=\"sh_symbol\">(<\/span>service<span class=\"sh_symbol\">)<\/span>\r\n    <span class=\"sh_type\">bool<\/span> <span class=\"sh_function\">create_directory<\/span><span class=\"sh_symbol\">(<\/span>path<span class=\"sh_symbol\">)<\/span> \r\n    <span class=\"sh_type\">bool<\/span> <span class=\"sh_function\">touch<\/span><span class=\"sh_symbol\">(<\/span>path<span class=\"sh_symbol\">)<\/span>                    <span class=\"sh_comment\">\/\/update modification date<\/span>\r\n    <span class=\"sh_usertype\">service_info<\/span> <span class=\"sh_function\">info<\/span><span class=\"sh_symbol\">()<\/span>                 <span class=\"sh_comment\">\/\/username, available disk space, etc<\/span>\r\n    <span class=\"sh_type\">bool<\/span> <span class=\"sh_function\">is_syncing<\/span><span class=\"sh_symbol\">()<\/span>\r\n<span class=\"sh_cbracket\">}<\/span><\/pre>\n<p>In\u00a0this one\u00a0<b>file<\/b>\u00a0is\u00a0a\u00a0struct with a\u00a0few important fields. What I\u00a0need is\u00a0path, size, timestamp and a\u00a0flag to\u00a0know whether this file is\u00a0a\u00a0directory. No\u00a0service-specific file id\u00a0and stuff. All the operations are declared in\u00a0<b>service<\/b>\u00a0and different backends implement those, using this common\u00a0<b>file<\/b>\u00a0struct.<\/p>\n<p>The other is\u00a0a\u00a0little bit more object-oriented:<\/p>\n<pre class=\"sh_c sh_sourceCode\">file <span class=\"sh_cbracket\">{<\/span>\r\n    path\r\n    name\r\n    size\r\n    timestamp\r\n    is_directory\r\n    service\r\n\r\n    file<span class=\"sh_symbol\">[]<\/span> <span class=\"sh_function\">list<\/span><span class=\"sh_symbol\">()<\/span>\r\n    <span class=\"sh_usertype\">file_contents<\/span> <span class=\"sh_function\">get_contents<\/span><span class=\"sh_symbol\">()<\/span>\r\n    <span class=\"sh_type\">bool<\/span> <span class=\"sh_function\">set_contents<\/span><span class=\"sh_symbol\">(<\/span>file_contents<span class=\"sh_symbol\">)<\/span>\r\n    <span class=\"sh_type\">bool<\/span> <span class=\"sh_function\">delete<\/span><span class=\"sh_symbol\">()<\/span>\r\n    <span class=\"sh_type\">bool<\/span> <span class=\"sh_function\">touch<\/span><span class=\"sh_symbol\">()<\/span>            <span class=\"sh_comment\">\/\/update modification date<\/span>\r\n    <span class=\"sh_type\">bool<\/span> <span class=\"sh_function\">sync<\/span><span class=\"sh_symbol\">(<\/span>file<span class=\"sh_symbol\">)<\/span>\r\n<span class=\"sh_cbracket\">}<\/span>\r\n\r\nservice <span class=\"sh_cbracket\">{<\/span>\r\n    <span class=\"sh_usertype\">file<\/span> <span class=\"sh_function\">get_root_directory<\/span><span class=\"sh_symbol\">()<\/span>\r\n    <span class=\"sh_usertype\">file<\/span> <span class=\"sh_function\">get_saves_directory<\/span><span class=\"sh_symbol\">()<\/span>\r\n    <span class=\"sh_type\">bool<\/span> <span class=\"sh_function\">create_directory<\/span><span class=\"sh_symbol\">(<\/span>path<span class=\"sh_symbol\">)<\/span> \r\n    <span class=\"sh_usertype\">service_info<\/span> <span class=\"sh_function\">info<\/span><span class=\"sh_symbol\">()<\/span>     <span class=\"sh_comment\">\/\/username, available disk space, etc<\/span>\r\n    <span class=\"sh_type\">bool<\/span> <span class=\"sh_function\">is_syncing<\/span><span class=\"sh_symbol\">()<\/span>\r\n<span class=\"sh_cbracket\">}<\/span><\/pre>\n<p>There\u00a0<b>file<\/b>\u00a0has a\u00a0reference to\u00a0the\u00a0<b>service<\/b>\u00a0it\u00a0belongs to\u00a0and includes all file-related operations. That means\u00a0I would have to\u00a0implement\u00a0<b>file<\/b>\u00a0backends as\u00a0well.<\/p>\n<p>The thing is\u00a0I\u2019m fine with both of\u00a0these approaches, and mentors opinions were divided. So, they advised me\u00a0to\u00a0write this post and get some feedback about\u00a0it.<\/p>\n<p>By\u00a0the way, I\u00a0also have an\u00a0idea of\u00a0making a\u00a0backend for local filesystem as\u00a0well. There is\u00a0an\u00a0AbstractFS in\u00a0ScummVM, but\u00a0I think it\u00a0would be\u00a0better to\u00a0use one small Wrapper over it\u00a0in\u00a0order to\u00a0work with local files in\u00a0terms of\u00a0the same API I\u2019m working with remote ones.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of\u00a0the most important tasks for my\u00a0project is\u00a0to\u00a0design the API right. That\u2019s something\u00a0I would start with, so\u00a0if\u00a0there are any mistakes or\u00a0wrong decisions, I\u2019d be\u00a0suffering from those later. Of\u00a0course, I\u00a0don\u2019t want to\u00a0suffer or\u00a0rewrite the API over and over again, so\u00a0I should think it\u00a0through. I\u00a0already mentioned\u00a0I wrote a\u00a0small prototype, which uses Dropbox API and has simple sync [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-12","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.scummvm.org\/tkachov\/wp-json\/wp\/v2\/posts\/12","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.scummvm.org\/tkachov\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.scummvm.org\/tkachov\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.scummvm.org\/tkachov\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.scummvm.org\/tkachov\/wp-json\/wp\/v2\/comments?post=12"}],"version-history":[{"count":1,"href":"https:\/\/blogs.scummvm.org\/tkachov\/wp-json\/wp\/v2\/posts\/12\/revisions"}],"predecessor-version":[{"id":13,"href":"https:\/\/blogs.scummvm.org\/tkachov\/wp-json\/wp\/v2\/posts\/12\/revisions\/13"}],"wp:attachment":[{"href":"https:\/\/blogs.scummvm.org\/tkachov\/wp-json\/wp\/v2\/media?parent=12"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/tkachov\/wp-json\/wp\/v2\/categories?post=12"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/tkachov\/wp-json\/wp\/v2\/tags?post=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}