Salesforce REST API入門：基礎から実装まで

## はじめに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/96410dea-5fc0-064d-c600-aea3a3d1b714.png)

SalesforceのREST APIは、外部システムとSalesforceのデータを連携する際の標準的なインターフェースです。この記事では、REST APIの基本的な概念から実際の実装例まで、段階的に解説していきます。

## 1. REST APIの基礎知識

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/d0924cda-4d00-d986-8a94-906b3640aa9c.png)

### RESTリソースとは

Salesforce REST APIでは、以下のような情報やアクションをリソースとして抽象化しています：

- データレコード（取引先、商談など）
- レコードのコレクション
- クエリ結果
- カスタムアクション

各リソースは固有のURI（Uniform Resource Identifier）で識別され、標準的なHTTPメソッドでアクセスします。

### REST要求の4つの構成要素

1. リソースURI：操作対象を指定
2. HTTPメソッド：実行する操作を指定（GET、POST、PATCH、DELETE）
3. 要求ヘッダー：メタデータや認証情報を指定
4. リクエストボディ：作成・更新時のデータを指定（必要な場合のみ）

## 2. Postmanを使用したAPI操作

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/67478d25-f6cc-9a99-af4a-28cad19d9630.png)

### SObject Describeの取得

Account（取引先）オブジェクトのメタデータを取得する例：

```http
GET /services/data/v58.0/sobjects/Account/describe
```

レスポンス形式は、要求ヘッダーで指定可能です：

```http
Accept: application/json
# または
Accept: application/xml
```

### 取引先レコードの作成

POSTリクエストの例：

```http
POST /services/data/v58.0/sobjects/Account
Content-Type: application/json

{
    "Name": "サンプル取引先",
    "ShippingCity": "東京"
}
```

成功時のレスポンス：

```json
{
    "id": "001xx000003DGZnAAO",
    "success": true,
    "errors": []
}
```

### クエリの実行

SOQLを使用したデータ検索：

```http
GET /services/data/v58.0/query/?q=SELECT Name From Account WHERE ShippingCity = 'Tokyo'
```

## 3. プログラミング実装例

### Node.jsでの実装（JSforce）

```javascript
const jsforce = require('jsforce');

// 接続の設定
const conn = new jsforce.Connection({
    loginUrl: 'https://login.salesforce.com'
});

// ログイン処理
async function login() {
    try {
        await conn.login('username@example.com', 'password' + 'securityToken');
        console.log('ログイン成功');
        
        // クエリの実行
        const results = await conn.query('SELECT Id, Name FROM Account LIMIT 5');
        console.log('取得レコード数:', results.totalSize);
        console.log('レコード:', results.records);
    } catch (err) {
        console.error('エラー:', err);
    }
}

login();
```

### Rubyでの実装（Restforce）

```ruby
require 'restforce'

# クライアントの初期化
client = Restforce.new(
  username: ENV['SALESFORCE_USERNAME'],
  password: ENV['SALESFORCE_PASSWORD'],
  security_token: ENV['SALESFORCE_SECURITY_TOKEN'],
  client_id: ENV['SALESFORCE_CLIENT_ID'],
  client_secret: ENV['SALESFORCE_CLIENT_SECRET']
)

# クエリの実行
accounts = client.query('SELECT Id, Name FROM Account LIMIT 5')
accounts.each do |account|
  puts "ID: #{account.Id}, Name: #{account.Name}"
end
```

## 4. 主な利用シーン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/f84f07ed-8ac5-46cb-7c1a-a61459993f12.png)

Salesforce REST APIは以下のような場面で活用できます：

- 外部システムとのデータ連携
- モバイルアプリケーションの開発
- カスタムインテグレーションの構築
- バッチ処理による大量データ処理

## 5. セキュリティと認証の注意点

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/b039d31d-3be1-01dc-93cb-87288781f6ef.png)

### 認証情報の適切な管理

- ユーザー名とパスワード
- セキュリティトークン
- クライアントIDとシークレット
- 接続アプリケーションの設定

## まとめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/0f6b0be9-0f89-631d-8899-74573ec09acb.png)

Salesforce REST APIを使用することで、外部システムとSalesforceを効率的に連携できます。基本的なHTTPの知識があれば、比較的容易に実装を始めることができます。

### 参考リンク

- [Salesforce REST API 開発者ガイド](https://developer.salesforce.com/docs/atlas.ja-jp.api_rest.meta/api_rest/)
- [JSforce Documentation](https://jsforce.github.io/)
- [Restforce GitHub](https://github.com/restforce/restforce)

## 参考情報 : REST API 主要エンドポイント一覧

| エンドポイント | メソッド | 説明 |
|--------------|---------|------|
| `/services/data/v59.0/sobjects/{Object名}` | GET | 指定したオブジェクトのメタデータを取得 |
| `/services/data/v59.0/sobjects/{Object名}/describe` | GET | オブジェクトの詳細な定義情報を取得 |
| `/services/data/v59.0/sobjects/{Object名}` | POST | 新規レコードを作成 |
| `/services/data/v59.0/sobjects/{Object名}/{レコードID}` | PATCH | 既存レコードを更新 |
| `/services/data/v59.0/sobjects/{Object名}/{レコードID}` | DELETE | レコードを削除 |
| `/services/data/v59.0/query?q={SOQL}` | GET | SOQLクエリを実行してレコードを検索 |
| `/services/data/v59.0/search?q={SOSL}` | GET | SOSLクエリを実行して全文検索 |
| `/services/data/v59.0/composite` | POST | 複数のAPI操作をまとめて実行 |
| `/services/data/v59.0/limits` | GET | API使用制限の情報を取得 |
| `/services/data/` | GET | 利用可能なAPIバージョンの一覧を取得 |

#### 重要な注意点

1. **APIバージョン**
   - 上記の例では`v59.0`を使用していますが、実際の開発では適切なバージョンを指定してください
   - 新しいバージョンがリリースされる際に、既存の機能に変更が加えられる可能性があります

2. **認証要件**
   - すべてのAPIコールには適切な認証が必要です
   - OAuth 2.0を使用した認証が推奨されています
   - アクセストークンをAuthorizationヘッダーに含める必要があります

3. **レスポンスフォーマット**
   - すべてのレスポンスはJSONフォーマットで返されます
   - エラーレスポンスも統一されたJSONフォーマットで返されます

4. **制限事項**
   - API使用には1日あたりの制限があります
   - 同時実行数にも制限があります
   - バルク操作を行う場合は専用のBulk APIの使用を検討してください

### 入力/出力フォーマット

#### レコード作成 (POST)
**入力例**:
```json
{
    "Name": "Sample Account",
    "Industry": "Technology",
    "Type": "Customer"
}
```

**成功時の出力例**:
```json
{
    "id": "001xx000003DGb0AAG",
    "success": true,
    "errors": []
}
```

#### レコード取得 (GET)
**出力例**:
```json
{
    "attributes": {
        "type": "Account",
        "url": "/services/data/v59.0/sobjects/Account/001xx000003DGb0AAG"
    },
    "Id": "001xx000003DGb0AAG",
    "Name": "Sample Account",
    "Industry": "Technology",
    "Type": "Customer",
    "CreatedDate": "2024-01-01T00:00:00.000+0000"
}
```

#### SOQLクエリ実行 (GET)
**出力例**:
```json
{
    "totalSize": 1,
    "done": true,
    "records": [
        {
            "attributes": {
                "type": "Account",
                "url": "/services/data/v59.0/sobjects/Account/001xx000003DGb0AAG"
            },
            "Id": "001xx000003DGb0AAG",
            "Name": "Sample Account"
        }
    ]
}
```

#### エラーレスポンス例
```json
{
    "errorCode": "INVALID_FIELD",
    "message": "No such column 'InvalidField' on sobject 'Account'",
    "fields": ["InvalidField"]
}
```

### 使用例

```http
GET /services/data/v59.0/sobjects/Account/describe HTTP/1.1
Host: yourInstance.salesforce.com
Authorization: Bearer <your_access_token>
```

```http
POST /services/data/v59.0/sobjects/Contact HTTP/1.1
Host: yourInstance.salesforce.com
Authorization: Bearer <your_access_token>
Content-Type: application/json

{
  "FirstName": "John",
  "LastName": "Doe",
  "Email": "john.doe@example.com"
}
```