Learn REST/HTTP

The following examples show you how to send RESTful HTTP requests to the directory server:

Before you try the examples, set up a server, as described in "Install a Directory Server".

ForgeRock Directory Services let you access directory data over HTTP as well as LDAP. The feature is known as REST to LDAP because it transforms REST operations into LDAP operations.

The server maps JSON resources to LDAP entries in order to convert HTTP operations to LDAP internally. The directory server you installed is bundled with a default mapping file for sample data. You can configure your own mapping depending on your directory data and the JSON objects you want.

REST to LDAP translation between JSON resources and LDAP entries
Prepare

Get the deployment CA certificate used to trust the server in the RESTful examples:

When using the Bash or Zsh examples with curl commands, get the deployment CA certificate in PEM format, which the curl command can read:

$ dskeymgr \
 export-ca-cert \
 --deploymentKey $DEPLOYMENT_KEY \
 --deploymentKeyPassword password \
 --outputFile ca-cert.pem
% dskeymgr \
 export-ca-cert \
 --deploymentKey $DEPLOYMENT_KEY \
 --deploymentKeyPassword password \
 --outputFile ca-cert.pem

For PowerShell examples, first configure Windows to trust the deployment CA certificate. Import the deployment CA from the server truststore using Microsoft Management Console (MMC):

  1. Run Microsoft Management Console (mmc.exe).

  2. Add the certificates snap-in so you can import the deployment CA certificate:

    1. In the console, select File > Add/Remove Snap-in, then Add.

    2. Select Certificates from the list of snap-ins and click Add.

    3. Finish the wizard.

  3. Import the deployment CA certificate using the snap-in:

    1. Select Console Root > Trusted Root Certification Authorities > Certificates.

    2. In the Action menu, select Import to open the wizard.

    3. Use the wizard to import the deployment CA certificate from the server truststore file, C:\path\to\opendj\config\keystore.

      The truststore password is the text in the file C:\path\to\opendj\config\keystore.pin.


Create

Use the REST API to create a user resource over HTTP:

$ curl \
 --request POST \
 --cacert ca-cert.pem \
 --user admin:password \
 --header "Content-Type: application/json" \
 --data '{
  "_id": "newuser",
  "_schema":"frapi:opendj:rest2ldap:user:1.0",
  "contactInformation": {
    "telephoneNumber": "+1 408 555 1212",
    "emailAddress": "newuser@example.com"
  },
  "name": {
    "givenName": "New",
    "familyName": "User"
  },
  "displayName": ["New User"],
  "manager": {
    "_id": "bjensen",
    "displayName": "Babs Jensen"
  }
 }' \
 https://localhost:8443/api/users?_prettyPrint=true
{
  "_id" : "newuser",
  "_rev" : "<revision>",
  "_schema" : "frapi:opendj:rest2ldap:user:1.0",
  "_meta" : {
    "created" : "<timestamp>"
  },
  "userName" : "newuser@example.com",
  "displayName" : [ "New User" ],
  "name" : {
    "givenName": "New",
    "familyName": "User"
  },
  "manager" : {
    "_id" : "bjensen",
    "_rev" : "<revision>"
  },
  "contactInformation" : {
    "telephoneNumber" : "+1 408 555 1212",
    "emailAddress" : "newuser@example.com"
  }
}
PS C:\path\to> $Credentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("admin:password"))
$Headers = @{
    Authorization = "Basic $Credentials"
}
Invoke-RestMethod `
 -Uri https://localhost:8443/api/users `
 -Method Post `
 -Headers $Headers `
 -ContentType application/json `
 -Body @"
 {
  "_id": "newuser",
  "_schema":"frapi:opendj:rest2ldap:user:1.0",
  "contactInformation": {
    "telephoneNumber": "+1 408 555 1212",
    "emailAddress": "newuser@example.com"
  },
  "name": {
    "givenName": "New",
    "familyName": "User"
  },
  "displayName": ["New User"],
  "manager": {
    "_id": "bjensen",
    "displayName": "Babs Jensen"
  }
 }
"@ | ConvertTo-JSON
{
    "_id":  "newuser",
    "_rev":  "<revision>",
    "_schema":  "frapi:opendj:rest2ldap:user:1.0",
    "_meta":  {
                  "created":  "<timestamp>"
              },
    "userName":  "newuser@example.com",
    "displayName":  [
                        "New User"
                    ],
    "name":  {
                 "givenName":  "New",
                 "familyName":  "User"
             },
    "manager":  {
                    "_id":  "bjensen",
                    "_rev":  "<revision>"
                },
    "contactInformation":  {
                               "telephoneNumber":  "+1 408 555 1212",
                               "emailAddress":  "newuser@example.com"
                           }
}
% curl \
 --request POST \
 --cacert ca-cert.pem \
 --user admin:password \
 --header "Content-Type: application/json" \
 --data '{
  "_id": "newuser",
  "_schema":"frapi:opendj:rest2ldap:user:1.0",
  "contactInformation": {
    "telephoneNumber": "+1 408 555 1212",
    "emailAddress": "newuser@example.com"
  },
  "name": {
    "givenName": "New",
    "familyName": "User"
  },
  "displayName": ["New User"],
  "manager": {
    "_id": "bjensen",
    "displayName": "Babs Jensen"
  }
 }' \
 "https://localhost:8443/api/users?_prettyPrint=true"
{
  "_id" : "newuser",
  "_rev" : "<revision>",
  "_schema" : "frapi:opendj:rest2ldap:user:1.0",
  "_meta" : {
    "created" : "<timestamp>"
  },
  "userName" : "newuser@example.com",
  "displayName" : [ "New User" ],
  "name" : {
    "givenName": "New",
    "familyName": "User"
  },
  "manager" : {
    "_id" : "bjensen",
    "_rev" : "<revision>"
  },
  "contactInformation" : {
    "telephoneNumber" : "+1 408 555 1212",
    "emailAddress" : "newuser@example.com"
  }
}
  • The command makes a secure connection to the server using HTTPS.

  • The user performing the HTTP POST is the directory superuser.

    The default authorization mechanism for HTTP access is HTTP Basic authentication. The superuser's HTTP user ID, admin, is mapped to the LDAP DN, uid=admin. REST to LDAP uses the DN and password to perform a simple LDAP bind for authentication. The directory can then use its LDAP-based access control mechanisms to authorize the operation.

  • The form of the JSON data respects the API defined by the mapping file. The example mapping file is a JSON format configuration file with comments. See /path/to/opendj/config/rest2ldap/endpoints/api/example-v1.json.

  • The successful response is the JSON resource that the command created.

    Fields whose names start with _ are reserved. For details, see "About ForgeRock Common REST".

For additional details, see "Create" and Create.


Read

Use the REST API to read the user resource created in "Create":

$ curl \
 --request GET \
 --cacert ca-cert.pem \
 --user bjensen:hifalutin \
 --header "Content-Type: application/json" \
 https://localhost:8443/api/users/newuser?_prettyPrint=true
{
  "_id" : "newuser",
  "_rev" : "<revision>",
  "_schema" : "frapi:opendj:rest2ldap:user:1.0",
  "_meta" : {
    "created" : "<timestamp>"
  },
  "userName" : "newuser@example.com",
  "displayName" : [ "New User" ],
  "name" : {
    "givenName": "New",
    "familyName": "User"
  },
  "manager" : {
    "_id" : "bjensen",
    "_rev" : "<revision>"
  },
  "contactInformation" : {
    "telephoneNumber" : "+1 408 555 1212",
    "emailAddress" : "newuser@example.com"
  }
}
PS C:\path\to> $Credentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("bjensen:hifalutin"))
$Headers = @{
    Authorization = "Basic $Credentials"
}
Invoke-RestMethod `
 -Uri https://localhost:8443/api/users/newuser `
 -Method Get `
 -Headers $Headers `
 -ContentType application/json | ConvertTo-JSON
{
    "_id":  "newuser",
    "_rev":  "<revision>",
    "_schema":  "frapi:opendj:rest2ldap:user:1.0",
    "_meta":  {
                  "created":  "<timestamp>"
              },
    "userName":  "newuser@example.com",
    "displayName":  [
                        "New User"
                    ],
    "name":  {
                 "givenName":  "New",
                 "familyName":  "User"
             },
    "manager":  {
                    "_id":  "bjensen",
                    "_rev":  "<revision>"
                },
    "contactInformation":  {
                               "telephoneNumber":  "+1 408 555 1212",
                               "emailAddress":  "newuser@example.com"
                           }
}
% curl \
 --request GET \
 --cacert ca-cert.pem \
 --user bjensen:hifalutin \
 --header "Content-Type: application/json" \
 "https://localhost:8443/api/users/newuser?_prettyPrint=true"
{
  "_id" : "newuser",
  "_rev" : "<revision>",
  "_schema" : "frapi:opendj:rest2ldap:user:1.0",
  "_meta" : {
    "created" : "<timestamp>"
  },
  "userName" : "newuser@example.com",
  "displayName" : [ "New User" ],
  "name" : {
    "givenName": "New",
    "familyName": "User"
  },
  "manager" : {
    "_id" : "bjensen",
    "_rev" : "<revision>"
  },
  "contactInformation" : {
    "telephoneNumber" : "+1 408 555 1212",
    "emailAddress" : "newuser@example.com"
  }
}

Notice that Babs Jensen authenticates for this HTTP GET request. If no credentials are specified, the response is the HTTP 401 Unauthorized:

{"code":401,"reason":"Unauthorized","message":"Invalid Credentials"}

In other words, the HTTP Basic authorization mechanism requires authentication even for read operations.

For additional details, see "Read" and Read. You can also query collections of resources as described in "Query" and Query.


Update

Use the REST API to replace the user resource created in "Create":

$ curl \
 --request PUT \
 --cacert ca-cert.pem \
 --user admin:password \
 --header "Content-Type: application/json" \
 --header "If-Match: *" \
 --data '{
  "_id": "newuser",
  "_schema":"frapi:opendj:rest2ldap:user:1.0",
  "contactInformation": {
    "telephoneNumber": "+1 234 567 8910",
    "emailAddress": "updated.user@example.com"
  },
  "name": {
    "givenName": "Updated",
    "familyName": "User"
  },
  "displayName": ["Updated User"],
  "manager": {
    "_id" : "bjensen",
    "displayName" : "Babs Jensen"
  }
 }' \
 https://localhost:8443/api/users/newuser?_prettyPrint=true
{
  "_id" : "newuser",
  "_rev" : "<revision>",
  "_schema" : "frapi:opendj:rest2ldap:user:1.0",
  "_meta" : {
    "created" : "<timestamp>"
  },
  "userName" : "newuser@example.com",
  "displayName" : [ "Updated User" ],
  "name" : {
    "givenName" : "Updated",
    "familyName" : "User"
  },
  "manager" : {
    "_id" : "bjensen",
    "_rev" : "<revision>"
  },
  "contactInformation" : {
    "telephoneNumber" : "+1 234 567 8910",
    "emailAddress" : "updated.user@example.com"
  }
}
PS C:\path\to> $Credentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("admin:password"))
$Headers = @{
    "Authorization" = "Basic $Credentials"
    "If-Match"      = "*"
}
Invoke-RestMethod `
 -Uri https://localhost:8443/api/users/newuser `
 -Method Put `
 -Headers $Headers `
 -ContentType application/json `
 -Body @"
 {
  "_id": "newuser",
  "_schema":"frapi:opendj:rest2ldap:user:1.0",
  "contactInformation": {
    "telephoneNumber": "+1 234 567 8910",
    "emailAddress": "updated.user@example.com"
  },
  "name": {
    "givenName": "Updated",
    "familyName": "User"
  },
  "displayName": ["Updated User"],
  "manager": {
    "_id" : "bjensen",
    "displayName" : "Babs Jensen"
  }
 }
"@ | ConvertTo-JSON
{
    "_id":  "newuser",
    "_rev":  "<revision>",
    "_schema":  "frapi:opendj:rest2ldap:user:1.0",
    "_meta":  {
                  "created":  "<timestamp>",
                  "lastModified":  "<timestamp>"
              },
    "displayName":  [
                        "Updated User"
                    ],
    "name":  {
                 "givenName":  "Updated",
                 "familyName":  "User"
             },
    "manager":  {
                    "_id":  "bjensen",
                    "_rev":  "<revision>"
                },
    "contactInformation":  {
                               "telephoneNumber":  "+1 234 567 8910"
                           }
}
% curl \
 --request PUT \
 --cacert ca-cert.pem \
 --user admin:password \
 --header "Content-Type: application/json" \
 --header "If-Match: *" \
 --data '{
  "_id": "newuser",
  "_schema":"frapi:opendj:rest2ldap:user:1.0",
  "contactInformation": {
    "telephoneNumber": "+1 234 567 8910",
    "emailAddress": "updated.user@example.com"
  },
  "name": {
    "givenName": "Updated",
    "familyName": "User"
  },
  "displayName": ["Updated User"],
  "manager": {
    "_id" : "bjensen",
    "displayName" : "Babs Jensen"
  }
 }' \
 "https://localhost:8443/api/users/newuser?_prettyPrint=true"
{
  "_id" : "newuser",
  "_rev" : "<revision>",
  "_schema" : "frapi:opendj:rest2ldap:user:1.0",
  "_meta" : {
    "created" : "<timestamp>"
  },
  "userName" : "newuser@example.com",
  "displayName" : [ "Updated User" ],
  "name" : {
    "givenName" : "Updated",
    "familyName" : "User"
  },
  "manager" : {
    "_id" : "bjensen",
    "_rev" : "<revision>"
  },
  "contactInformation" : {
    "telephoneNumber" : "+1 234 567 8910",
    "emailAddress" : "updated.user@example.com"
  }
}

Resources are versioned using revision numbers. A revision is specified in the resource's _rev field. The --header "If-Match: *" ensures the resource is replaced, regardless of its revision. Alternatively, you can set --header "If-Match: revision" to replace only the expected revision of the resource.

For additional details, see "Update" and Update. You can also patch resources instead of replacing them entirely. See "Patch" and Patch.


Delete

Use the REST API to delete the user resource updated in "Update":

$ curl \
 --request DELETE \
 --cacert ca-cert.pem \
 --user admin:password \
 --header "Content-Type: application/json" \
 https://localhost:8443/api/users/newuser?_prettyPrint=true
{
  "_id" : "newuser",
  "_rev" : "<revision>",
  "_schema" : "frapi:opendj:rest2ldap:user:1.0",
  "_meta" : {
    "created" : "<timestamp>"
  },
  "userName" : "newuser@example.com",
  "displayName" : [ "Updated User" ],
  "name" : {
    "givenName" : "Updated",
    "familyName" : "User"
  },
  "manager" : {
    "_id" : "bjensen",
    "_rev" : "<revision>"
  },
  "contactInformation" : {
    "telephoneNumber" : "+1 234 567 8910",
    "emailAddress" : "updated.user@example.com"
  }
}
PS C:\path\to> $Credentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("admin:password"))
$Headers = @{
    Authorization = "Basic $Credentials"
}
Invoke-RestMethod `
 -Uri https://localhost:8443/api/users/newuser `
 -Method Delete `
 -Headers $Headers `
 -ContentType application/json | ConvertTo-JSON
{
    "_id":  "newuser",
    "_rev":  "<revision>",
    "_schema":  "frapi:opendj:rest2ldap:user:1.0",
    "_meta":  {
                  "created":  "<timestamp>",
                  "lastModified":  "<timestamp>"
              },
    "displayName":  [
                        "Updated User"
                    ],
    "name":  {
                 "givenName":  "Updated",
                 "familyName":  "User"
             },
    "manager":  {
                    "_id":  "bjensen",
                    "_rev":  "<revision>"
                },
    "contactInformation":  {
                               "telephoneNumber":  "+1 234 567 8910"
                           }
}
% curl \
 --request DELETE \
 --cacert ca-cert.pem \
 --user admin:password \
 --header "Content-Type: application/json" \
 "https://localhost:8443/api/users/newuser?_prettyPrint=true"
{
  "_id" : "newuser",
  "_rev" : "<revision>",
  "_schema" : "frapi:opendj:rest2ldap:user:1.0",
  "_meta" : {
    "created" : "<timestamp>"
  },
  "userName" : "newuser@example.com",
  "displayName" : [ "Updated User" ],
  "name" : {
    "givenName" : "Updated",
    "familyName" : "User"
  },
  "manager" : {
    "_id" : "bjensen",
    "_rev" : "<revision>"
  },
  "contactInformation" : {
    "telephoneNumber" : "+1 234 567 8910",
    "emailAddress" : "updated.user@example.com"
  }
}

For additional details, see "Delete" and Delete.


Read a different version of :