はじめに
とあるカンファレンスで Hexabase
を知る機会があり、せっかくなので触ってみようと思いたち...
Hexabase とは
Hexabase は、企業システムの開発に利用できるエンタープライズ BaaS(Backend as a Service)です。Web アプリケーション開発に活用できる高品質なバックエンド機能をクラウドサービスとして提供します。Hexabase を利用することで、開発期間と開発コストをおさえながら、使い勝手の要となるフロントエンド開発に注力できます。
(引用:Hexabase 開発ガイド)
今回は 「Hexabase開発ツアー」 を一通りやってみて、その過程で API のアクセスがあったので、せっかくなので Swift で操作してみました。
そんなに難しいことはしていないので、メモだと思って呼んでいただけますとmm
Hexabase を触ってみる
セットアップ
基本的にはサイトにある通りに進めていけば大丈夫です。
1点注意として、SNS 連携でアカウントを作ってしまうと、パスワードが必要な場面で困ってしまう(パスワードがない)ので、登録したアドレスからパスワードをリセットする必要があります。
API で操作してみる
この部分は、Step5.APIでバックエンドにアクセスする に相当します。
0. API の簡易クライアントを用意する
過去に色々と記事を書いてきたので、ちゃんとしたものを作りたい人は以下を参照ください🙏
今回は簡単にアクセスしたいので、簡易なものを用意します。
準備として以下を用意しておき
import Combine
final class APIClient {
static let shared = APIClient()
private init() {}
private let decorder: JSONDecoder = {
let jsonDecoder = JSONDecoder()
jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase
return jsonDecoder
}()
}
こちらにそれぞれのリクエストを追加していきます。
1. APIでloginする
以下が仕様書になっているので
- Method
Post https://api.hexabase.com/api/v0/login
- Request
{
"email": "foo@example.net",
"password": "**********"
}
- Response
{
"token": "xxxx"
}
それに対応してレスポンスクラスを用意し
struct LoginResponseEntity: Decodable {
let token: String
}
通信するために先ほど用意したクラスに、メソッドを追加します。
func login(email: String, password: String) -> AnyPublisher<LoginResponseEntity, Error> {
let params = ["email": email, "password": password]
var request = URLRequest(url: URL(string: "https://api.hexabase.com/api/v0/login")!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.httpBody = try! JSONSerialization.data(withJSONObject: params)
return URLSession.shared
.dataTaskPublisher(for: request)
.map(\.data)
.decode(type: LoginResponseEntity.self, decoder: decorder)
.eraseToAnyPublisher()
}
実際にアクセスする際は
APIClient.shared.login(email: "your_address@xxx.com", password: "your_password")
.sink(receiveCompletion: { result in
switch result {
case .failure(let error):
print("failure", error)
case .finished:
print("finished")
}
}, receiveValue: { response in
print("receiveValue", response.token)
})
.store(in: &cancellables)
これでトークンを取得できるようになります。
2. APIでワークスペースを選択する
以下が仕様書になっているので
- Method
Get https://api.hexabase.com/api/v0/workspaces
- Request Header
Authorization: Bearer XXXXXX_TOKEN_XXXXXX
- Response
{
"workspaces": [
{
"workspace_id": "60594049dabf490001d84684",
"workspace_name": "demo_workspace"
},
{
"workspace_id": "60d45d336d66ed844b1190fe",
"workspace_name": "demo_developer"
}
],
"current_workspace_id": "60d45d336d66ed844b1190fe"
}
それに対応してレスポンスクラスを用意し
struct WorkspaceResponseEntity: Decodable {
let workspaces: [WorkspaceEntity]
}
struct WorkspaceEntity: Decodable {
let workspaceId: String
let workspaceName: String
}
通信するために先ほど用意したクラスに、メソッドを追加します。
func getWorkspaces(token: String) -> AnyPublisher<WorkspaceResponseEntity, Error> {
var request = URLRequest(url: URL(string: "https://api.hexabase.com/api/v0/workspaces")!)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.setValue( "Bearer \(token)", forHTTPHeaderField: "Authorization")
return URLSession.shared
.dataTaskPublisher(for: request)
.map(\.data)
.decode(type: WorkspaceResponseEntity.self, decoder: decorder)
.eraseToAnyPublisher()
}
実際にアクセスする際は
APIClient.shared.getWorkspaces(token: "your_token")
.sink(receiveCompletion: { result in
switch result {
case .failure(let error):
print("failure", error)
case .finished:
print("finished")
}
}, receiveValue: { workspace in
print("receiveValue", workspace)
})
.store(in: &cancellables)
これでワークスペースの一覧を取得できます。
3. APIでアプリケーション情報を取得する
以下が仕様書になっているので
- Method
Get https://api.hexabase.com/api/v0/workspaces/:workspace-id/applications
- Params
workspace_id: xxxx_your_workspace_id_xxxx
- Request Header
Authorization: Bearer XXXXXX_TOKEN_XXXXXX
- Response
[
{
"application_id": "60d45d336d66ed844b119101",
"name": "新しいアプリケーション",
"display_id": "new_app",
"datastores": [
{
"datastore_id": "60d45d51dbf1fd0948253d8d",
"name": "新しいデータベース",
"display_id": "new_db"
}
]
},
{
"application_id": "60d5b2bbfc2b8d27e799d8b6",
"name": "hexa-simple-example",
"display_id": "APP-todo1",
"datastores": [
{
"datastore_id": "60d5b2bb77d6297bc49699de",
"name": "TODOサンプル",
"display_id": "Db-todo1"
}
]
}
]
それに対応してレスポンスクラスを用意し
struct WorkspaceObjectEntity: Decodable {
let applicationId: String
let name: String
let displayId: String
let datastores: [WorkspaceData]
}
struct WorkspaceData: Decodable {
let datastoreId: String
let name: String
let displayId: String
}
通信するために先ほど用意したクラスに、メソッドを追加します。
func accessWorkspace(token: String, id: String) -> AnyPublisher<[WorkspaceObjectEntity], Error> {
var request = URLRequest(url: URL(string: "https://api.hexabase.com/api/v0/workspaces/\(id)/applications")!)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.setValue( "Bearer \(token)", forHTTPHeaderField: "Authorization")
return URLSession.shared
.dataTaskPublisher(for: request)
.map(\.data)
.decode(type: [WorkspaceObjectEntity].self, decoder: decorder)
.eraseToAnyPublisher()
}
実際にアクセスする際は
APIClient.shared.accessWorkspace(token: "your_token", id: "your_workspace_id")
.sink(receiveCompletion: { result in
switch result {
case .failure(let error):
print("failure", error)
case .finished:
print("finished")
}
}, receiveValue: { object in
print("receiveValue", object)
})
.store(in: &self.cancellables)
ワークスペースにアクセスできました。
一旦ここまでとしますmm
終わりに
ドキュメントもしっかりしているので、比較的簡単に実装をすることができました!
チャットサービスも可能で、Webフロントはデモコードがあったので、興味がある人は呼んでみると面白いかと思います。
今回はデモコードとして簡単なコードになっていることをご容赦くださいmm