microsoft / microsoft/typespec
Emit types only and exclude HTTP libraries
- Dominant language
- Java
- Stars
- 5.9k
- Forks
- 394
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 104
Description
### Clear and concise description of the problem
Dear Team,
thank you for the great work on TypeSpec. It's a really neat project 😍
Would it be possible to emit types only?
Let me try to explain. I have created a demo repo that was initiated via `tsp init` and uses the following emitters
- `@typespec/http-client-java`
- `@typespec/http-client-js`
The JS output is super nice and already does what I need. When I look into `tsp-output/clients/js/src/models/models.ts` I find the TypeScript types, e.g.
```ts
export interface Widget {
id: string;
weight: number;
color: "red" | "blue";
}
```
I can import those types into my own project and would have type safety for our REST API 👍
It would be nice if I could do the same for the Java output. To provide some context. We follow the Google API guideline, e.g.
- [Resource-oriented design -> Methods](https://google.aip.dev/121#methods)
- [Standard methods: Create](https://google.aip.dev/133)
In the REST / CRUDL (Create, Read, Update, Delete, List) world we would have the following types for creating a widget:
- `CreateWidgetRequest`
- `CreateWidgetResponse`
In modern Java those requests would be [Records](https://docs.oracle.com/en/java/javase/17/language/records.html). You usually have Records to talk to the outside world and in your application you'd use Classes / Entities for database communication.
A `CreateWidgetRequest` would look like this
```json
{
"weight": 1,
"color": "red"
}
```
and the corresponding response would look like this
```json
{
"id": "123abc"
"weight": 1,
"color": "red"
}
```
As you can see there is no `id` for response as the `id` is usually generated on the database level.
The Java records would look like this
```java
record CreateWidgetRequest(int weight, String color) { }
```
and
```java
record CreateOrganizationResponse(String id, int weight, String color) {}
```
When I look into my demo repo I can see the generated `Widget.java` class that looks like this
```java
/**
* The Widget model.
*/
@Metadata(properties = { MetadataProperties.IMMUTABLE })
public final class Widget implements JsonSerializable {
/*
* The id property.
*/
@Metadata(properties = { MetadataProperties.GENERATED })
private final String id;
/*
* The weight property.
*/
@Metadata(properties = { MetadataProperties.GENERATED })
private final int weight;
/*
* The color property.
*/
@Metadata(properties = { MetadataProperties.GENERATED })
private final WidgetColor color;
// and so much more
```
Can I somehow tell TypeSpec to emit Records instead of full blown Classes?
Somehow related but a bit different: Can I emit types only and do not care about http libraries?
In every language we have so many HTTP libraries. In the Node.js ecosystem we have
- axios
- fetch
- got
- ky
- superagent
- ... and so many more
In addition to those we have dedicated http libraries for the major frontend frameworks, e.g. React, Vue, Angular and so on.
The same is true for Java and especially the Spring Boot ecosystem
- RestClient
- WebClient
- RestTemplate
- HTTP Interface
- ... and so many more
It's probably impossible to generate nice client for all those usecases and I wonder whether it might be a first nice step to generate types only and let the HTTP integration to the customer / end user?
Thank you 😍 TypeSpec is awesome!
To sum it up 😁 Can I specify the following (maybe via the config):
1. Emit Java Records for selected models
2. Emit types only (no HTTP libraries)
### Checklist
- [x] Follow our [Code of Conduct](https://github.com/microsoft/typespec/blob/main/CODE_OF_CONDUCT.md)
- [x] Read the [docs](https://typespec.io/docs/).
- [x] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
Contributor guide
Assessment
This issue has not been assessed yet.