sidebar_position | sidebar_label | description | keywords | seoFrontMatterUpdated | |||||
---|---|---|---|---|---|---|---|---|---|
3 |
Format datetime objects |
Learn how to easily format datetime objects and send back human-readable formatted data. |
|
false |
import GraphiQLIDE from "@site/src/components/GraphiQLIDE"; import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem";
In this recipe, you'll learn how to convert an existing datetime object from your supergraph into a human-readable format. This approach is perfect when you want to streamline your frontend by formatting data at the API level, allowing the UI to easily render the formatted result with minimal effort.
:::info Prerequisites
Before continuing, ensure you have:
- A local Hasura DDN project.
- A lambda connector added to your project.
- A type in your supergraph that is a valid datetime object.
NB: The type will vary with your database-of-choice, but anything that is ISO-8601-compliant will generally work for what's listed below. You can adapt this recipe to fit your individual needs.
:::
```typescript title="In your functions.ts file, add the following:"
/**
* @readonly
*/
export function formattedDate(dateString: string): string {
const date = new Date(dateString);
return date.toLocaleString("en-US", {
year: "numeric",
month: "long",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
hour12: true,
});
}
```
```python title="In your functions.py file, add the following:"
from hasura_ndc import start
from hasura_ndc.function_connector import FunctionConnector
from datetime import datetime
connector = FunctionConnector()
@connector.register_query
async def formatted_date(dateString: str) -> str:
date = datetime.fromisoformat(date_string)
return date.strftime("%B %d, %Y %I:%M %p")
if __name__ == "__main__":
start(connector)
```
```go title="In a Go file inside your functions directory, add the following:"
package functions
import (
"context"
"fmt"
"time"
"hasura-ndc.dev/ndc-go/types"
)
// DatetimeArguments defines the input arguments for the function
type DatetimeArguments struct {
DateString string `json:"date_string"` // required argument
}
// DatetimeResult defines the output result for the function
type DatetimeResult string
// FunctionFormattedDate formats a datetime string
func FunctionFormattedDate(ctx context.Context, state *types.State, arguments *DatetimeArguments) (*DatetimeResult, error) {
date, err := time.Parse(time.RFC3339, arguments.DateString)
if err != nil {
return nil, fmt.Errorf("failed to parse date: %v", err)
}
formattedDate := date.Format("January 02, 2006 03:04 PM")
result := DatetimeResult(formattedDate)
return &result, nil
}
```
To add your function, generate the related metadata that will link together any functions in your lambda connector's source files and your API:
ddn connector introspect <connector_name>
Then, you can generate an hml
file for the function using the following command:
ddn command add <connector_name> "*"
Assuming the input argument's type matches that of a type belonging to one or more of your models, you can create a relationship to the command. This will enable you to make nested queries that will invoke your custom business logic using the value of the field from the related model!
Create a relationship in the corresponding model's HML file.
---
kind: Relationship
version: v1
definition:
name: formattedDate
sourceType: Orders
target:
command:
name: FormattedDate
mapping:
- source:
fieldPath:
- fieldName: createdAt
target:
argument:
argumentName: dateString
Create a new build of your supergraph:
ddn supergraph build local
In your project's explorer, you should see the new function exposed as a type and should be able to make a query like this:
<GraphiQLIDE
query={query SimpleFormattedDateQuery { formattedDate(dateString: "2023-09-19T10:15:30+02:00") }
}
response={{ "data": { "formattedDate": "September 19, 2023 at 08:15 AM" } }
}
/>
If you created a relationship, you can make a query like this, too:
<GraphiQLIDE
query={query OrdersQuery { orders { id status formattedDate } }
}
response={{ "data": { "orders": [ { "id": "c7406b75-6b24-41e4-9c5b-ff3feada9447", "status": "processing", "formattedDate": "October 29, 2023 at 05:02 PM" }, { "id": "7ff13435-b590-4d6b-957f-f7fd39d4528a", "status": "complete", "formattedDate": "October 29, 2023 at 05:02 PM" }, { "id": "98612470-1feb-4b91-88f7-9289d652ee87", "status": "complete", "formattedDate": "October 29, 2023 at 05:02 PM" }, { "id": "85581445-752a-4aef-9684-b648eb5d5f42", "status": "complete", "formattedDate": "October 29, 2023 at 05:02 PM" }, { "id": "9891596a-a732-4c1c-902c-1a112da48fec", "status": "complete", "formattedDate": "October 29, 2023 at 05:02 PM" } ] } }
}
/>
In this guide, you learned how to enhance your API and enrich the data it serves for its consumers by incorporating custom business logic directly into your supergraph. By leveraging lambda connectors with relationships, you can not only add custom business logic, but easily pass values to it and return this information as part of existing models.
- TypeScript Node.js connector.
- Python connector.
- Go connector.