# Jakarta JSON Processing (JSON-P) en Quarkus: Manipulación Programática de JSON

## **Introducción**

Jakarta JSON Processing (JSON-P) proporciona APIs para crear, parsear, transformar y consultar JSON de forma programática. A diferencia de JSON-Binding, JSON-P te da control total sobre la estructura JSON.

## **¿Qué es JSON-Processing?**

JSON-P ofrece dos APIs principales:

1. **Object Model API**: Para manipular JSON como objetos (JsonObject, JsonArray)
    
2. **Streaming API**: Para procesar JSON grande de forma eficiente (JsonParser, JsonGenerator)
    

## **Object Model API**

### **Crear JsonObject**

```go
JsonObjectBuilder builder = Json.createObjectBuilder();
builder.add("name", "Superman")
       .add("powerLevel", 95)
       .add("isActive", true);

// Objeto anidado
JsonObjectBuilder locationBuilder = Json.createObjectBuilder();
locationBuilder.add("city", "Metropolis");
builder.add("location", locationBuilder);

// Array
JsonArrayBuilder abilitiesBuilder = Json.createArrayBuilder();
abilitiesBuilder.add("Super strength").add("Flight");
builder.add("abilities", abilitiesBuilder);

JsonObject hero = builder.build();
```

### **Crear JsonArray**

```go
JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();

JsonObjectBuilder hero1 = Json.createObjectBuilder();
hero1.add("name", "Superman").add("powerLevel", 95);
arrayBuilder.add(hero1);

JsonObjectBuilder hero2 = Json.createObjectBuilder();
hero2.add("name", "Batman").add("powerLevel", 85);
arrayBuilder.add(hero2);

JsonArray heroes = arrayBuilder.build();
```

### **Parsear JSON**

```go
String jsonString = "{\"name\":\"Superman\",\"powerLevel\":95}";
JsonReader reader = Json.createReader(new StringReader(jsonString));
JsonObject jsonObject = reader.readObject();
reader.close();
```

### **Escribir con Formato**

```go
Map<String, Object> config = Map.of(JsonGenerator.PRETTY_PRINTING, true);
JsonWriterFactory factory = Json.createWriterFactory(config);
StringWriter writer = new StringWriter();
JsonWriter jsonWriter = factory.createWriter(writer);
jsonWriter.writeObject(jsonObject);
jsonWriter.close();
String formattedJson = writer.toString();
```

## **JsonPointer (RFC 6901) - Querying JSON**

JsonPointer permite consultar valores específicos en JSON:

```go
// Consultar un valor
JsonPointer pointer = Json.createPointer("/name");
JsonValue value = pointer.getValue(jsonObject);

// Agregar un valor
JsonPointer pointer = Json.createPointer("/newField");
JsonObject modified = pointer.add(jsonObject, Json.createValue("newValue"));

// Eliminar un valor
JsonPointer pointer = Json.createPointer("/fieldToRemove");
JsonObject modified = pointer.remove(jsonObject);
```

## **JsonPatch (RFC 6902) - Transformar JSON**

JsonPatch permite transformar JSON usando operaciones estándar:

```go
// Crear operaciones de patch
JsonArrayBuilder patchBuilder = Json.createArrayBuilder();

// Operación: reemplazar
JsonObjectBuilder replaceOp = Json.createObjectBuilder();
replaceOp.add("op", "replace")
         .add("path", "/powerLevel")
         .add("value", 98);
patchBuilder.add(replaceOp);

// Operación: agregar
JsonObjectBuilder addOp = Json.createObjectBuilder();
addOp.add("op", "add")
     .add("path", "/newField")
     .add("value", "newValue");
patchBuilder.add(addOp);

JsonArray patchOperations = patchBuilder.build();

// Aplicar patch
JsonPatch patch = Json.createPatch(patchOperations);
JsonObject transformed = patch.apply(original);
```

## **Streaming API**

### **JsonParser - Parsear JSON Grande**

```go
JsonParser parser = Json.createParser(new StringReader(jsonString));

while (parser.hasNext()) {
    JsonParser.Event event = parser.next();
    
    switch (event) {
        case KEY_NAME:
            String key = parser.getString();
            break;
        case VALUE_STRING:
            String value = parser.getString();
            break;
        case VALUE_NUMBER:
            if (parser.isIntegralNumber()) {
                long number = parser.getLong();
            } else {
                BigDecimal decimal = parser.getBigDecimal();
            }
            break;
        // ... más eventos
    }
}
parser.close();
```

### **JsonGenerator - Generar JSON Grande**

```go
Map<String, Object> config = Map.of(JsonGenerator.PRETTY_PRINTING, true);
JsonGenerator generator = Json.createGeneratorFactory(config)
    .createGenerator(writer);

generator.writeStartObject()
         .write("name", "Superman")
         .write("powerLevel", 95)
         .writeStartObject("location")
             .write("city", "Metropolis")
         .writeEnd()
         .writeStartArray("abilities")
             .write("Super strength")
             .write("Flight")
         .writeEnd()
         .writeEnd();

generator.close();
```

## **Filtrar y Transformar**

### **Filtrar JsonArray**

```go
JsonArrayBuilder filteredBuilder = Json.createArrayBuilder();

for (JsonValue heroValue : heroesArray) {
    if (heroValue.getValueType() == JsonValue.ValueType.OBJECT) {
        JsonObject hero = heroValue.asJsonObject();
        int powerLevel = hero.getInt("powerLevel", 0);
        
        if (powerLevel >= minPowerLevel) {
            filteredBuilder.add(hero);
        }
    }
}

JsonArray filtered = filteredBuilder.build();
```

## **Comparación: JSON-Processing vs JSON-Binding**

| **Característica** | **JSON-Processing** | **JSON-Binding** |
| --- | --- | --- |
| Propósito | Manipulación programática | Serialización automática |
| API | JsonObject, JsonArray | Anotaciones en clases Java |
| Uso | Cuando necesitas control total | Cuando trabajas con objetos Java |
| Streaming | Sí (JsonParser/Generator) | No |
| Querying | Sí (JsonPointer) | No |
| Transformations | Sí (JsonPatch) | No |

## **Ejemplo Completo**

Nuestro demo muestra:

* Creación de JsonObject y JsonArray programáticamente
    
* Parsing de JSON strings
    
* Escritura con formato
    
* JsonPointer para consultar JSON
    
* JsonPatch para transformar JSON
    
* Streaming API para JSON grande
    
* Filtrado y transformación
    

## **Ventajas en Quarkus**

1. **Control Total**: Manipulación completa de JSON
    
2. **Streaming**: Eficiente para JSON grande
    
3. **Estándares**: JsonPointer y JsonPatch son RFCs estándar
    
4. **Flexibilidad**: Útil cuando JSON-Binding no es suficiente
    

## **Conclusión**

JSON-Processing es perfecto cuando necesitas manipular JSON directamente o cuando JSON-Binding no cubre tus necesidades. Las APIs de streaming son especialmente útiles para procesar JSON grande.

## **Recursos**

* [Demo completo](file:///Users/josediaz/Projects/JoeDayz/jakartaee-2026/quarkus-demos/json-processing/)
    
* [Jakarta JSON Processing Specification](https://jakarta.ee/specifications/jsonp/)
    
* [RFC 6901 - JSON Pointer](https://tools.ietf.org/html/rfc6901)
    
* [RFC 6902 - JSON Patch](https://tools.ietf.org/html/rfc6902)
