---
sidebar_label: MySQL service example
doc_id: e902c591-1a13-418b-b212-15b1f4bbf061
description: >-
  Guide for defining MySQL as a reusable service in nullplatform with
  centralized management and entity linking.
keywords:
  - MySQL
  - nullplatform
  - database integration
  - service configuration
  - Sequelize
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# MySQL service integration example

In this guide, you’ll learn how to define a MySQL service in nullplatform so you can manage it centrally and link it to other entities.

### How it works

A MySQL service configuration represents a MySQL database instance. It includes the key attributes used to connect and operate with the database.


```mermaid
graph TB;
    subgraph Service["<b>MySQL service</b>"]
        direction LR
        
        note1["References a MySQL database instance"]
    end
    
    Service-.->|Links| Development
    Service-.->|Links| Production

    subgraph Development["<b>Development database</b>"]
        direction TB
       
        note4["Exports Database info as parameters: <br> - DB_HOST: dev.my-db.domain.com <br> - DB_PORT: 3306 <br> - DB_USER: my-dev-db-user <br> - DB_PASS: ***** <br> - DB_NAME: users-db <br> - ... "]
       
    end
    
    subgraph Production["<b>Production database</b>"]
        direction TB
       
        note5["Exports Database info as parameters: <br> - DB_HOST: prod.my-db.domain.com <br> - DB_PORT: 3306 <br> - DB_USER: my-prod-db-user <br> - DB_PASS: ***** <br> - DB_NAME: users-db <br> - ... "]
       
    end
    
    Development-.->|Inject parameters| DevScope
    Production-.->|Inject parameters| ProdScope
    
    subgraph Application["<b>User API - Application</b>"]
        direction TB
        
        DevScope["Dev scope"]-->DevCode;
        
        DevCode["const { Sequelize } = require('sequelize'); <br>const dbHost = env.DB_HOST; <br>const dbPort = env.DB_PORT; <br>const dbUser = env.DB_USER; <br>const dbPass = env.DB_PASS; <br>const dbName = env.DB_NAME; <br>const sequelize = new Sequelize(<br>‎ ‎ ‎ ‎ ‎ ‎ dbName,<br>‎ ‎ ‎ ‎ ‎ ‎ dbUser,<br>‎ ‎ ‎ ‎ ‎ ‎ dbPass, <br>‎ ‎ ‎ ‎ ‎ ‎ {<br>‎ ‎ ‎ ‎ ‎ ‎  ‎ ‎ ‎ ‎ host: dbHost,<br>‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ port: dbPort,<br>‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ dialect: 'mysql' <br>‎ ‎ ‎ ‎ ‎ ‎ }<br>);"]
        
        ProdScope["Prod scope"]-->DevCode;
        
        DevCode~~~note2["Same code across all environments; <br> only parameter values change to point to the correct database instance"];
    end 
    
    classDef box fill:#0ea5e9,stroke:#0284c7,stroke-width:1.4px,color:#0f172a;
    classDef note fill:#111827,stroke:#475569,color:#e2e8f0,font-size:14px;
    classDef invisible fill:none,stroke:none;
    classDef list fill:#0b172a,stroke:#475569,color:#e2e8f0,text-align:left,font-size:12px;
    classDef codeStyle font-family:Consolas, 'SFMono-Regular', Menlo, monospace, fill:#0b172a, stroke:#334155, stroke-width:1.2px, font-size:12px, text-align:left, color:#e2e8f0;

    class note1,note2,note3 note
    class note4,note5 list
    class Initial,BlueGreen box
    classDef blank fill:none,stroke:none;
    class blank1,blank2,blank3,blank4,blank5 blank
    class DevCode codeStyle;

```

:::note Diagram breakdown

This service refers to a MySQL database instance, which includes key parameters for connecting to the database:

**Attributes**:
>- **Host**: The address of the MySQL database server.
>- **Port**: The port number used for MySQL connections.
>- **Size**: The tier of the database instance.

**Links: development and production environments**

The MySQL service is linked to the application through two environments, each with its own configuration:

>1. Development link - properties:
>    - **Database**: The development database name.
>    - **Username**: Credential for accessing the MySQL database in development.
>    - **Password**: Password for the development database.

>2. Production link - properties:
>    - **Database**: The production database name.
>    - **Username**: Credential for accessing the MySQL database in production.
>    - **Password**: Password for the production database.

**Automatic parameter integration**

These attributes and properties are passed as parameters into the application configuration, making it easy to switch between environments without code changes.
:::

This setup helps manage MySQL database connections in a straightforward way, so you can switch between development and production environments without changing code.


## 1. Craft your service specification

The example below shows how to craft a MySQL service specification tailored to your organization’s settings.

You can create a service spec using our [CLI](/docs/cli/) or [API](/docs/api/service-specification-create). 


<Tabs
defaultValue="create-service-spec-cli"
values={[
{ label: 'CLI', value: 'create-service-spec-cli' },
{ label: 'cURL', value: 'create-service-spec-curl' },
]}>
<TabItem value="create-service-spec-cli">

```bash
np service specification create \
  --body '{
    "name": "MySQL service",
    "visible_to": ["organization=12345:account=12345:namespace=28"],
    "type": "dependency",
    "dimensions": {},
    "use_default_actions": true,
    "attributes" : {
      "schema": {
        "type": "object",
        "required": ["host", "port"],
        "properties": {
          "host": {
            "type": "string",
            "export": true,
            "readOnly": true,
            "visibleOn": [
              "read",
              "update"
            ],
            "editableOn": []
          },
          "port": {
            "type": "integer",
            "export": true,
            "default": 3306,
            "readOnly": true,
            "visibleOn": [
              "read",
              "update"
            ],
            "editableOn": []
          },
          "size": {
            "enum": [
              "small",
              "medium",
              "large"
            ],
            "type": "string",
            "default": "small",
            "visibleOn": [
              "read",
              "create",
              "update"
            ],
            "editableOn": ["create"]
          }        
        },
        "additionalProperties": false
      }, 
      "values": {}
    },
    "selectors": {
      "category": "Database",
      "imported": false,
      "provider": "AWS",
      "sub_category": "Relational Database"
    }
  }
```

  </TabItem>
  <TabItem value="create-service-spec-curl">

  ```bash
  curl -L -X POST 'https://api.nullplatform.com/service_specification' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer the-token' \
  -d '{
      "name": "MySQL service",
      "visible_to": ["organization=12345:account=12345:namespace=28"],
      "type": "dependency",
      "dimensions": {},
      "use_default_actions": true,
      "attributes" : {
        "schema": {
          "type": "object",
          "required": ["host", "port"],
          "properties": {
            "host": {
              "type": "string",
              "export": true,
              "readOnly": true,
              "visibleOn": [
                "read",
                "update"
              ],
              "editableOn": []
            },
            "port": {
              "type": "integer",
              "export": true,
              "default": 3306,
              "readOnly": true,
              "visibleOn": [
                "read",
                "update"
              ],
              "editableOn": []
            },
            "size": {
              "enum": [
                "small",
                "medium",
                "large"
              ],
              "type": "string",
              "default": "small",
              "visibleOn": [
                "read",
                "create",
                "update"
              ],
              "editableOn": ["create"]
            }        
          },
          "additionalProperties": false
        }, 
        "values": {}
      },
      "selectors": {
        "category": "Database",
        "imported": false,
        "provider": "AWS",
        "sub_category": "Relational Database"
      }
    }
  ```
  </TabItem>
</Tabs>

:::note Request details

- `visible_to`: This service is exclusively visible within the namespace `28` of the specified organization and account: `organization=12345:account=12345:namespace=28`.
- `use_default_actions`: Enables the default set of actions (**create**, **update**, and **delete**) for this service.
- `attributes` define the required connection and configuration details used by applications that rely on this MySQL instance:

  - `host`: The hostname or IP address where the MySQL server is running. This value is marked as read-only and is exported for use in downstream services.
  - `port`: The port number MySQL uses to accept connections, typically `3306`. This is also read-only and exported.
  - `size`: An enum field representing the size tier of the database instance. Accepts values `"small"`, `"medium"`, or `"large"`. Editable during creation only and visible throughout the lifecycle.

- [Special schema keys](/docs/json-ui-schema/json-schema):

  - `visibleOn`: Controls when a property is shown in the UI (e.g., `read`, `create`, `update`).
  - `editableOn`: Controls when a property can be edited. An empty array means the property cannot be modified at any stage.
:::


For more details, refer to [Create service specification](/docs/api/service-specification-create) in our API docs.

## 2. Create the link specification

Next, define how other entities can connect to the service, specifying credentials and database name.

As with service specs, you can craft link specifications using our [CLI](/docs/cli/) or our [API](/docs/api/link-specification-create). 

<Tabs
defaultValue="create-link-spec-cli"
values={[
{ label: 'CLI', value: 'create-link-spec-cli' },
{ label: 'cURL', value: 'create-link-spec-curl' },
]}>
<TabItem value="create-link-spec-cli">

    ```bash
    np link-specification create \
     --body '{
      "name": "Link MySQL Database",
      "unique": false,
      "attributes" : {
        "schema": {
          "type": "object",
          "required": ["username", "password", "name"],
          "properties": {
            "name": {
              "type": "string",
              "export": true,
              "readOnly": false,
              "visibleOn": [
                "create",
                "update"
              ],
              "editableOn": ["create"]
            },
            "password": {
              "type": "string",
              "export": {
                "type": "environment_variable",
                "secret": true
              },
              "readOnly": true,
              "visibleOn": [
                "create"
              ],
              "editableOn": []
            },
            "username": {
              "type": "string",
              "export": true,
              "readOnly": true,
              "visibleOn": [
              "create"
              ],
              "editableOn": []
            }
          },
          "additionalProperties": false
        }, 
        "values": {}
      },
      "specification_id": "f3da5e42-87cb-49d3-b108-4c6b9fd7202b"
    }
    ```

  </TabItem>
  <TabItem value="create-link-spec-curl">

  ```bash
  curl -L 'https://api.nullplatform.com/link_specification' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer the-token' \
  -d '{
    "name": "Link MySQL Database",
    "unique": false,
    "attributes" : {
      "schema": {
        "type": "object",
        "required": ["username", "password", "name"],
        "properties": {
          "name": {
            "type": "string",
            "export": true,
            "readOnly": false,
            "visibleOn": [
              "create",
              "update"
            ],
            "editableOn": ["create"]
          },
          "password": {
            "type": "string",
            "export": {
              "type": "environment_variable",
              "secret": true
            },
            "readOnly": true,
            "visibleOn": [
              "create"
            ],
            "editableOn": []
          },
          "username": {
            "type": "string",
            "export": true,
            "readOnly": true,
            "visibleOn": [
            "create"
            ],
            "editableOn": []
          }
        },
        "additionalProperties": false
      }, 
      "values": {}
    },
    "specification_id": "f3da5e42-87cb-49d3-b108-4c6b9fd7202b"
  }
  ```
  </TabItem>
</Tabs>



This link exports credentials and schema parameters to any application using this MySQL service, with sensitive data managed securely as secrets.

For more details, refer to [Create a link specification](/docs/api/link-specification-create) in our API docs.


### Security and permissions

Each defined element comes with its own permissions and access control, so you can manage who can create and use resources and where they can be deployed.
