# Crear o actualizar una colección

`PUT https://data.inovacc.dev/v1/databases/{database}/collections/{collection}`

Crea una colección, o cambia sus campos y reglas, enviando su estado deseado completo.

## Parámetros de la ruta

- `database` (string), obligatorio: La clave de la base de datos.
- `collection` (string), obligatorio: El nombre de la colección: una letra minúscula, seguida de letras minúsculas, dígitos o `_`, hasta 63 caracteres.

## Parámetros del cuerpo

- `mode` ("schema" | "free"): `schema` (el predeterminado) declara campos tipados; `free` guarda documentos JSON sin esquema.
- `fields` (array): Hasta 64 campos. Los campos que solo están en la lista nueva se agregan, los que solo están en la lista anterior se eliminan junto con sus datos; un campo presente en ambas debe ser idéntico.
- `fields[].name` (string), obligatorio: El nombre del campo; no `id`, `version`, `created_at`, `updated_at` ni uno que empiece con `_`.
- `fields[].type` (string), obligatorio: `text`, `integer`, `number`, `bool`, `datetime`, `json`, `relation` o `blob`.
- `fields[].required` (boolean): Se verifica en cada escritura.
- `fields[].unique` (boolean): Dos registros no pueden compartir un valor. No en `json` ni `blob`.
- `fields[].indexed` (boolean): Indexa el campo para filtros y ordenamientos. No en `json` ni `blob`.
- `fields[].fulltext` (boolean): Busca en el campo con `q`. Solo en `text`.
- `fields[].target` (string): Para una `relation`: la colección a la que apuntan los ids de registro.
- `rules` (object): `list`, `view`, `create`, `update` y `delete`, cada una `null` (nadie), `""` (credenciales del servidor), `public`, `users` o una expresión. Si se omite el objeto, todas las reglas quedan en `null`.

## Encabezados

- `Authorization` (string), obligatorio: Bearer <clave de API>
- `Content-Type` (string), obligatorio: application/json, en una llamada con cuerpo

## Solicitud

**cURL**

```sh
curl -X PUT "https://data.inovacc.dev/v1/databases/{database}/collections/{collection}" \
  -H "Authorization: Bearer $INOVACC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "mode": "schema",
  "fields": [
    {
      "name": "owner",
      "type": "text",
      "required": true
    },
    {
      "name": "body",
      "type": "text"
    }
  ],
  "rules": {
    "list": "owner = @auth.id",
    "view": "owner = @auth.id",
    "create": "@auth.kind = \"end_user\" && owner = @auth.id",
    "update": "owner = @auth.id",
    "delete": "owner = @auth.id"
  }
}'
```

**TypeScript**

```ts
const body: Record<string, unknown> = {
  "mode": "schema",
  "fields": [
    {
      "name": "owner",
      "type": "text",
      "required": true
    },
    {
      "name": "body",
      "type": "text"
    }
  ],
  "rules": {
    "list": "owner = @auth.id",
    "view": "owner = @auth.id",
    "create": "@auth.kind = \"end_user\" && owner = @auth.id",
    "update": "owner = @auth.id",
    "delete": "owner = @auth.id"
  }
};

const url = "https://data.inovacc.dev/v1/databases/{database}/collections/{collection}";

const response = await fetch(url, {
  method: "PUT",
  headers: {
    Authorization: `Bearer ${process.env.INOVACC_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(body),
});

console.log(response.status, await response.text());
```

**Python**

```py
import json
import os
import urllib.request

body = {
    "mode": "schema",
    "fields": [
        {
            "name": "owner",
            "type": "text",
            "required": True,
        },
        {
            "name": "body",
            "type": "text",
        },
    ],
    "rules": {
        "list": "owner = @auth.id",
        "view": "owner = @auth.id",
        "create": "@auth.kind = \"end_user\" && owner = @auth.id",
        "update": "owner = @auth.id",
        "delete": "owner = @auth.id",
    },
}

request = urllib.request.Request(
    "https://data.inovacc.dev/v1/databases/{database}/collections/{collection}",
    data=json.dumps(body).encode(),
    method="PUT",
    headers={
        "User-Agent": "inovacc-python-sample",
        "Authorization": "Bearer " + os.environ["INOVACC_API_KEY"],
        "Content-Type": "application/json",
    },
)

with urllib.request.urlopen(request) as response:
    print(response.status, response.read().decode())
```

**Go**

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

const url = "https://data.inovacc.dev/v1/databases/{database}/collections/{collection}"

const body = `{
  "mode": "schema",
  "fields": [
    {
      "name": "owner",
      "type": "text",
      "required": true
    },
    {
      "name": "body",
      "type": "text"
    }
  ],
  "rules": {
    "list": "owner = @auth.id",
    "view": "owner = @auth.id",
    "create": "@auth.kind = \"end_user\" && owner = @auth.id",
    "update": "owner = @auth.id",
    "delete": "owner = @auth.id"
  }
}`

func main() {
	req, err := http.NewRequest("PUT", url, strings.NewReader(body))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INOVACC_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	out, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(res.Status, string(out))
}
```

**Rust**

```rs
// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
// Cargo.toml: serde_json = "1"

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let api_key = std::env::var("INOVACC_API_KEY")?;
    let body = serde_json::json!({
        "mode": "schema",
        "fields": [
            {
                "name": "owner",
                "type": "text",
                "required": true
            },
            {
                "name": "body",
                "type": "text"
            }
        ],
        "rules": {
            "list": "owner = @auth.id",
            "view": "owner = @auth.id",
            "create": "@auth.kind = \"end_user\" && owner = @auth.id",
            "update": "owner = @auth.id",
            "delete": "owner = @auth.id"
        }
    });
    let response = reqwest::blocking::Client::new()
        .put("https://data.inovacc.dev/v1/databases/{database}/collections/{collection}")
        .bearer_auth(api_key)
        .json(&body)
        .send()?;
    println!("{} {}", response.status(), response.text()?);
    Ok(())
}
```

**JavaScript**

```mjs
const body = {
  "mode": "schema",
  "fields": [
    {
      "name": "owner",
      "type": "text",
      "required": true
    },
    {
      "name": "body",
      "type": "text"
    }
  ],
  "rules": {
    "list": "owner = @auth.id",
    "view": "owner = @auth.id",
    "create": "@auth.kind = \"end_user\" && owner = @auth.id",
    "update": "owner = @auth.id",
    "delete": "owner = @auth.id"
  }
};

const url = "https://data.inovacc.dev/v1/databases/{database}/collections/{collection}";

const response = await fetch(url, {
  method: "PUT",
  headers: {
    Authorization: `Bearer ${process.env.INOVACC_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(body),
});

console.log(response.status, await response.text());
```

**PHP**

```php
<?php

$body = <<<'JSON'
{
  "mode": "schema",
  "fields": [
    {
      "name": "owner",
      "type": "text",
      "required": true
    },
    {
      "name": "body",
      "type": "text"
    }
  ],
  "rules": {
    "list": "owner = @auth.id",
    "view": "owner = @auth.id",
    "create": "@auth.kind = \"end_user\" && owner = @auth.id",
    "update": "owner = @auth.id",
    "delete": "owner = @auth.id"
  }
}
JSON;

$curl = curl_init('https://data.inovacc.dev/v1/databases/{database}/collections/{collection}');
curl_setopt_array($curl, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('INOVACC_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => $body,
]);

$response = curl_exec($curl);
echo curl_getinfo($curl, CURLINFO_HTTP_CODE), ' ', $response, "\n";
curl_close($curl);
```

**Ruby**

```rb
require "net/http"
require "uri"

uri = URI('https://data.inovacc.dev/v1/databases/{database}/collections/{collection}')
body = <<~'JSON'
{
  "mode": "schema",
  "fields": [
    {
      "name": "owner",
      "type": "text",
      "required": true
    },
    {
      "name": "body",
      "type": "text"
    }
  ],
  "rules": {
    "list": "owner = @auth.id",
    "view": "owner = @auth.id",
    "create": "@auth.kind = \"end_user\" && owner = @auth.id",
    "update": "owner = @auth.id",
    "delete": "owner = @auth.id"
  }
}
JSON

request = Net::HTTP::Put.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch('INOVACC_API_KEY')}"
request["Content-Type"] = "application/json"
request.body = body

response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

puts "#{response.code} #{response.body}"
```

**Java**

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Main {
    public static void main(String[] args) throws Exception {
        String apiKey = System.getenv("INOVACC_API_KEY");
        String body = "{" +
                "\"mode\": \"schema\"," +
                "\"fields\": [" +
                "{" +
                "\"name\": \"owner\"," +
                "\"type\": \"text\"," +
                "\"required\": true" +
                "}," +
                "{" +
                "\"name\": \"body\"," +
                "\"type\": \"text\"" +
                "}" +
                "]," +
                "\"rules\": {" +
                "\"list\": \"owner = @auth.id\"," +
                "\"view\": \"owner = @auth.id\"," +
                "\"create\": \"@auth.kind = \\\"end_user\\\" && owner = @auth.id\"," +
                "\"update\": \"owner = @auth.id\"," +
                "\"delete\": \"owner = @auth.id\"" +
                "}" +
                "}";

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://data.inovacc.dev/v1/databases/{database}/collections/{collection}"))
                .header("Authorization", "Bearer " + apiKey)
                .header("Content-Type", "application/json")
                .method("PUT", HttpRequest.BodyPublishers.ofString(body))
                .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
                .send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.statusCode() + " " + response.body());
    }
}
```

**C#**

```cs
using System.Text;

var body = "{" +
    "\"mode\": \"schema\"," +
    "\"fields\": [" +
    "{" +
    "\"name\": \"owner\"," +
    "\"type\": \"text\"," +
    "\"required\": true" +
    "}," +
    "{" +
    "\"name\": \"body\"," +
    "\"type\": \"text\"" +
    "}" +
    "]," +
    "\"rules\": {" +
    "\"list\": \"owner = @auth.id\"," +
    "\"view\": \"owner = @auth.id\"," +
    "\"create\": \"@auth.kind = \\\"end_user\\\" && owner = @auth.id\"," +
    "\"update\": \"owner = @auth.id\"," +
    "\"delete\": \"owner = @auth.id\"" +
    "}" +
    "}";

var url = "https://data.inovacc.dev/v1/databases/{database}/collections/{collection}";
var apiKey = Environment.GetEnvironmentVariable("INOVACC_API_KEY");

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Put, url);
request.Headers.Add("Authorization", $"Bearer {apiKey}");
request.Content = new StringContent(body, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");
```

**Kotlin**

```kt
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse

fun main() {
    val apiKey = System.getenv("INOVACC_API_KEY")
    val body = "{" +
        "\"mode\": \"schema\"," +
        "\"fields\": [" +
        "{" +
        "\"name\": \"owner\"," +
        "\"type\": \"text\"," +
        "\"required\": true" +
        "}," +
        "{" +
        "\"name\": \"body\"," +
        "\"type\": \"text\"" +
        "}" +
        "]," +
        "\"rules\": {" +
        "\"list\": \"owner = @auth.id\"," +
        "\"view\": \"owner = @auth.id\"," +
        "\"create\": \"@auth.kind = \\\"end_user\\\" && owner = @auth.id\"," +
        "\"update\": \"owner = @auth.id\"," +
        "\"delete\": \"owner = @auth.id\"" +
        "}" +
        "}"

    val request = HttpRequest.newBuilder()
        .uri(URI.create("https://data.inovacc.dev/v1/databases/{database}/collections/{collection}"))
        .header("Authorization", "Bearer " + apiKey)
        .header("Content-Type", "application/json")
        .method("PUT", HttpRequest.BodyPublishers.ofString(body))
        .build()

    val response = HttpClient.newHttpClient()
        .send(request, HttpResponse.BodyHandlers.ofString())
    println("${response.statusCode()} ${response.body()}")
}
```

**Swift**

```swift
import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

let body = #"""
{
  "mode": "schema",
  "fields": [
    {
      "name": "owner",
      "type": "text",
      "required": true
    },
    {
      "name": "body",
      "type": "text"
    }
  ],
  "rules": {
    "list": "owner = @auth.id",
    "view": "owner = @auth.id",
    "create": "@auth.kind = \"end_user\" && owner = @auth.id",
    "update": "owner = @auth.id",
    "delete": "owner = @auth.id"
  }
}
"""#

let apiKey = ProcessInfo.processInfo.environment["INOVACC_API_KEY"] ?? ""

let url = URL(string: "https://data.inovacc.dev/v1/databases/{database}/collections/{collection}")!
var request = URLRequest(url: url)
request.httpMethod = "PUT"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = Data(body.utf8)

let (data, response) = try await URLSession.shared.data(for: request)
let status = (response as? HTTPURLResponse)?.statusCode ?? 0
print(status, String(decoding: data, as: UTF8.self))
```

## Respuesta

**201**

```json
{
  "name": "items",
  "mode": "schema",
  "schema_version": 1,
  "fields": [
    {
      "name": "owner",
      "type": "text",
      "required": true
    },
    {
      "name": "body",
      "type": "text"
    }
  ],
  "rules": {
    "list": "owner = @auth.id",
    "view": "owner = @auth.id",
    "create": "@auth.kind = \"end_user\" && owner = @auth.id",
    "update": "owner = @auth.id",
    "delete": "owner = @auth.id"
  }
}
```

**400**: invalid_body, invalid_name, invalid_schema, invalid_rule, schema_change_unsupported, unique_needs_single_shard

**401**: invalid_credentials

**403**: forbidden

**404**: database_not_found

**409**: schema_violation

**429**: rate_limited

**503**: service_unavailable

## Ver también

- [Autenticación](https://developer.inovacc.dev/es/guides/authentication/)
- [Errores](https://developer.inovacc.dev/es/guides/errors/)
- [Límites](https://developer.inovacc.dev/es/guides/limits/)
