この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
APIを作るとき
みなさん、毎日API使ってますか?私は、ワンライナーでAPIをコールすることにハマっています。さて、いつも使っているAPIを作る側になったとき、どのように設計していますでしょうか?また、作ったAPIをどのように使ってもらっていますか?そんな疑問に応えるサービスがApiaryです。
Apiaryとは?
Apiaryは、REST APIをサクッと書けるサービスです。また、APIドキュメントも生成してくれます。モックサーバも提供してくれます。API利用サンプルコードも作ってくれます。うん、使わないって選択肢は無いですねw。
無料登録すると早速使えるようになります。チームでプライベートなAPI開発をしたければ有料プランを選択してください。
API開発の流れ
API開発の流れは、まずはじめにMarkdown形式でドキュメントを書きます。既にサンプルがあるのでこれを使ってみましょう。
右側にドキュメントのプレビューが現れましたね。さっそく使ってみましょう。List all Notesを選択します。すると、APIのモックを利用できる画面が出てきます。
ドキュメントを書いただけなのにAPIを実行できました!
CORS設定
API利用時にCORS(クロスドメインアクセス)をしたいときがありますよね。Apiaryの設定画面でON/OFF可能です。
サンプルコードの利用
できあがったモックAPIサーバを利用するサンプルコードも自動生成されます。これはありがたいですね!
cURL
curl --include \
'http://private-ee96-satoshi7.apiary-mock.com/notes'
Java
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;
Client client = ClientBuilder.newClient();
Response response = client.target("http://private-ee96-satoshi7.apiary-mock.com")
.path("/notes")
.request(MediaType.TEXT_PLAIN_TYPE)
.get();
System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
JavaScript
var Request = new XMLHttpRequest();
Request.open('GET', 'http://private-ee96-satoshi7.apiary-mock.com/notes');
Request.onreadystatechange = function () {
if (this.readyState === 4) {
console.log('Status:', this.status);
console.log('Headers:', this.getAllResponseHeaders());
console.log('Body:', this.responseText);
}
};
Request.send(JSON.stringify(body));
Node.js
var request = require('request');
request('http://private-ee96-satoshi7.apiary-mock.com/notes', function (error, response, body) {
console.log('Status:', response.statusCode);
console.log('Headers:', JSON.stringify(response.headers));
console.log('Response:', body);
});
Perl
require LWP::UserAgent;
my $ua = LWP::UserAgent->new;
my $response = $ua->get("http://private-ee96-satoshi7.apiary-mock.com/notes");
print $response->as_string;
Python
from urllib2 import Request, urlopen
request = Request('http://private-ee96-satoshi7.apiary-mock.com/notes')
response_body = urlopen(request).read()
print response_body
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://private-ee96-satoshi7.apiary-mock.com/notes");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
$response = curl_exec($ch);
curl_close($ch);
var_dump($response);
[/code]
<h4>Ruby</h4>
<h4>Go</h4>
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
client := &http.Client{}
req, _ := http.NewRequest("GET", "http://private-ee96-satoshi7.apiary-mock.com/notes", nil)
resp, err := client.Do(req)
if err != nil {
fmt.Println("Errored when sending request to the server")
return
}
defer resp.Body.Close()
resp_body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(resp.Status)
fmt.Println(string(resp_body))
}
C#
using System;
using System.Net.Http;
var baseAddress = new Uri("http://private-ee96-satoshi7.apiary-mock.com/");
using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{
using(var response = await httpClient.GetAsync("notes"))
{
string responseData = await response.Content.ReadAsStringAsync();
}
}
VisualBasic
Dim request = TryCast(System.Net.WebRequest.Create("http://private-ee96-satoshi7.apiary-mock.com/notes"), System.Net.HttpWebRequest)
request.Method = "GET"
request.ContentLength = 0
Dim responseContent As String
Using response = TryCast(request.GetResponse(), System.Net.HttpWebResponse)
Using reader = New System.IO.StreamReader(response.GetResponseStream())
responseContent = reader.ReadToEnd()
End Using
End Using
Groovy
import groovyx.net.http.RESTClient
import static groovyx.net.http.ContentType.JSON
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
@Grab (group = 'org.codehaus.groovy.modules.http-builder', module = 'http-builder', version = '0.5.0')
def client = new RESTClient("http://private-ee96-satoshi7.apiary-mock.com")
response = client.get( path : "/notes")
println("Status:" + response.status)
if (response.data) {
println("Content Type: " + response.contentType)
println("Body:\n" + JsonOutput.prettyPrint(JsonOutput.toJson(response.data)))
}
Objective-C
NSURL *URL = [NSURL URLWithString:@"http://private-ee96-satoshi7.apiary-mock.com/notes"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:@"GET"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
// Handle error...
return;
}
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSLog(@"Response HTTP Status code: %ld\n", (long)[(NSHTTPURLResponse *)response statusCode]);
NSLog(@"Response HTTP Headers:\n%@\n", [(NSHTTPURLResponse *)response allHeaderFields]);
}
NSString* body = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Response Body:\n%@\n", body);
}];
[task resume];
Swift
let url = NSURL(string: "http://private-ee96-satoshi7.apiary-mock.com/notes")!
let request = NSMutableURLRequest(URL: url)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data: NSData!, response: NSURLResponse!, error: NSError!) in
if error != nil {
// Handle error...
return
}
println(error)
println(response)
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
Swift Representor
import Alamofire
import Representor
let blueprint = Blueprint(named: "blueprint.json", bundle: nil)
let baseURL = NSURL(string: "http://private-ee96-satoshi7.apiary-mock.com/")
if let transition = blueprint?.transition("Notes Collection", action: "List all Notes") {
request(baseURL, transition, parameters:parameters)
.response { (request, response, data, error) in
// Handle the response
}
}
まとめ
Markdownを書いたらAPIとドキュメントが出来上がっていますので、クライアントサイドとサーバーサイドで後からごにょごにょ繋げるのではなく、先にAPI(アプリケーションをプログラミングするときに使うインタフェース)部分を決めることで、開発は大分楽になるのではないでしょうか。